java基础10( IO流 )

一. IO

1.1 io分类

1.按照流的流向分,可以分为输入流和输出流;
2.按照操作单元划分,可以划分为字节流和字符流;
3.按照流的角色划分为节点流和处理流。

所有的输入流的基类:
InputStream(字节) Reader(字符)
所有输出流的基类:
OutputStream(字节) Writer(字符)

1.2 BIO,NIO,AIO 有什么区别?

BIO是一个连接一个线程:
同步并阻塞
线程发起IO请求,不管内核是否准备好IO操作,从发起请求起,线程一直阻塞,直到操作完成。NIO是一个请求一个线程。
适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JDK1.4以前的唯一选择,但程序直观简单易理解

NIO是一个请求一个线程:
同步非阻塞
线程发起IO请求,立即返回;内核在做好IO操作的准备之后,通过调用注册的回调函数通知线程做IO操作,线程开始阻塞,直到操作完成
适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,并发局限于应用中,编程比较复杂,JDK1.4开始支持

AIO是一个有效请求一个线程:
异步非阻塞
线程发起IO请求,立即返回;内存做好IO操作的准备之后,做IO操作,直到操作完成或者失败,通过调用注册的回调函数通知线程做IO操作完成或者失败。
用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分调用OS参与并发操作,编程比较复杂,JDK7开始支持

1.3 IO流_体系结构

1.字节流:可以操作任何文件
a.输出流:OutputStream(抽象类)(三种输出方法)
|—FileOutputStream(基本类)
|—FilterOutputStream
|—BufferedOutputStream(缓存流)(无特有方法)
b.输入流:InputStream(抽象类)(俩种读取方法)
|—FileInputStream(基本类)
|—FilterInputStream
|—BufferedInputStream(缓存流)(无特有方法)

2.字符流:只能操作存文本文件
a.输出流:Writer(抽象类)(五种输出方法)
|—OutputStreamWriter(转换流):指定字符集
|—FileWrite(子类)
|—BufferedWriter(缓冲流)–除提供缓存区,有特有方法
newLine():根据平台输出一个换行符;
b.输入流:Reader(抽象类)(两种读取的方法)
|–InputStreamReader(转换流):指定字符集
|–FileReader(子类)
|–BufferedReader(缓冲流)-除提供缓存区,有特有方法
String readLine():一次读取一行。

1.3.1 IO流_字节流

1.1 输出流 FileOutputStream

构造方法:
FileOutputStream(String name) :(覆盖)创建文件输出流以指定的名称写入文件。
FileOutputStream(String name, boolean append) (追加)创建文件输出流以指定的名称写入文件。
FileOutputStream(File file):(覆盖)创建文件输出流以写入由指定的 File对象表示的文件。
FileOutputStream(File file, boolean append) (追加)创建文件输出流以写入由指定的 File对象表示的文件。
注意:
Java中所有的“输出流”构造时,文件可以不存在,会自动创建一个;
写入的方法:(三种)
write(int b):输出一个字节;
write(byte[] byteArray):输出一个字节数组;
write(byte[] byteArray,int off,int len):输出字节数组的一部分;
byteArray : 要写入的数组;
off : 起始位置索引;
len : 输出的数量;
示例代码:

public static void main(String[] args) throws IOException {
    //1.构造方法:
    FileOutputStream out = new FileOutputStream("demo12.txt",false);

    //2.输出的方法:
    //2-1:write(int b):输出一个字节
    out.write(97);//97 --> 转换为二进制: 0110 0001 --> 写入文件:0110 0001
    out.write(999997);//999997 -->转换为二进制:111101000010 0011 1101 --> 取最低的一个字节:写入文件:0011 1101

    //2-2:write(byte[] byteArray):输出多个字节
    byte[] byteArray = {97, 98, 99, 100};
    out.write(byteArray);
     //间接的输出一个“字符串” 
     out.write("大家好,呵呵".getBytes());
     //输出一个换行符:
     out.write("\r\n".getBytes());


    //2-3:write(byte[] byteArray,int offset,int len):
    //例如:写入byteArray数组中的99,100
    out.write(byteArray,2,2);
    //关闭流--成为垃圾--释放资源
     out.close();
}

注意:
String类的getBytes()方法可以将此字符串转换为一个byte[]数组
换行:"\r\n"
流用完后,要记得“关闭”,用于“释放资源”。

1.1 输入流 FileInputStream

构造方法:
FileInputStream(String name) 通过打开与实际文件的连接来创建一个 FileInputStream 该文件由文件系统中的路径名 name命名。
FileInputStream(File file) 通过打开与实际文件的连接创建一个 FileInputStream 该文件由文件系统中的 File对象 file命名。
注意:
Java中所有的“输入流”构造时,文件必须存在,否则抛出异常;
读取的方法(两种)
public int read():读取一个字节
public int read(byte[] byteArray):读取多个字节,封装到参数数组中。
示例代码:

public class Demo {
    public static void main(String[] args) throws IOException {
        File file = new File("demo13.txt");
        if (!file.exists()) {
            file.createNewFile();
        }
        FileInputStream in = new FileInputStream(file);

        //读一个字节
        /*int b = 0;
        while ((b = in.read()) != -1) {
            System.out.println((char)b);
        }*/

        //读取多个字节:3个
        byte[] byteArray = new byte[3];
        int len = 0;
        while ((len = in.read(byteArray)) != -1) {
            //将 byte[]数组转换为String
            String str = new String(byteArray,0,len);
            System.out.println("转换为String后:" + str);
        }
    }
}

1.3.2 IO流_字符流

1.1输出流 FileWriter

1.构造方法:
FileWriter(String fileName)(覆盖)构造一个给定文件名的FileWriter对象。
FileWriter(String fileName, boolean append) (追加)
构造一个FileWriter对象,给出一个带有布尔值的文件名,表示是否附加写入的数据。
FileWriter(File file)(覆盖) 给一个File对象构造一个FileWriter对象。
FileWriter(File file, boolean append)(追加) 给一个File对象构造一个FileWriter对象。
2.输出方法:(五个)
write(int c):输出一个字符;
write(char[] chArray):输出一个字符数组;
write(char[] chArray,int off,int len):输出字符数组的一部分;
write(String str):输出一个字符串;
write(String str,int off,int len):输出字符串的一部分;
3.示例代码:

public static void main(String[] args) throws IOException {
        //注意:构造时,文件可以不存在,会自动创建
        FileWriter out = new FileWriter("demo02.txt");

        //**********五个输出的方法*************************************//
        //1.write(int c):输出一个字符
        out.write(98);
        //2.write(char[] chArray):输出一个字符数组
        char[] chArray = {'a','b','你','号','呵','呵'};
        out.write(chArray);

        //3.write(char[] chArray,int off,int len("输出字符数组的一部分;
        out.write(chArray,4,2);

        //4.write(String s):输出一个字符串
        out.write("我爱Java");

        //5.write(String s,int off,int len):输出字符串的一部分
        String str = "我爱北京天安门";
        out.write(str,4,3);

        //*******************输出换行************************//
        out.write("\r\n");
        out.write("你好");
        //刷新缓存区
//        out.flush();
	   //注意:"字符流"内部自带缓存区,write()之后一定要flush()/close()才能
	   //将缓存区的数据写入到文件。
        out.close();//相当于:flush() + close()
    }

1.2. 输出流 转换流OutputStreamWriter

构造方法:
1.OutputStreamWriter(OutputStream out):使用一个“字节流对象”构造一个“转换流对象”,可以实现第一个作用。

public static void main(String[] args) {
    //将"字节流对象"转换为"字符流对象"
    try (OutputStreamWriter out = new OutputStreamWriter(
					new FileOutputStream("demo06.txt"))) {
		  //"字符"通向"字节"的桥梁
        out.write("呵呵");//程序中:字符 --> 编码表:UTF-8 -->十进制编码-->二进制 -->文件(字节)
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

2.OutputStreamWriter(OutputStream out, String charsetName):使用一个字节流,和一个“编码表”的名字类构造一个输出流

public static void main(String[] args) {
    //将"字节流对象"转换为"字符流对象",同时,又指定了编码表
    try (OutputStreamWriter out = new OutputStreamWriter(
				new FileOutputStream("demo06.txt"),"UTF-8")) {
        out.write("呵呵");//程序中:字符 --> 编码表:UTF-8 -->十进制编码-->二进制 -->文件(字节)
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

2.1输入流 FileReader

1.构造方法:
FileReader(String fileName) 创建一个新的 FileReader ,给定要读取的文件的名称。
FileReader(File file) 创建一个新的 FileReader ,给出 File读取。
2.读取的方法:
int read():读取一个字符;返回值:读取的字符的“编码”
int read(char[] chArray):读取多个字符,存储到字符数组中。(读取一个字符数组)
返回值:读取的字符的“数量”。
3.示例代码:

public static void main(String[] args) throws IOException {
    FileReader in = new FileReader("demo03.txt");

    //一次读取一个字符
    /*int c = 0;
    while ((c = in.read()) != -1) {
        System.out.println("读取的字符:" + (char)c);
    }*/

    //一次读取一个字符数组
    char[] chArray = new char[2];
    int len = 0;
    while ((len = in.read(chArray)) != -1) {
        //可以将一个字符数组的一部分转换为String
        String str = new String(chArray,0,len);
        System.out.println(str);
    }

    //关闭
    in.close();
}
				

2.2. 输入流 转换流InputStreamReader

构造方法:
1.public InputStreamReader(InputStream in):使用一个“字节输入流”构造

public static void main(String[] args) {
	     //将“字节流”转换为“字符流”,而且使用系统默认编码:UTF-8
    try (InputStreamReader in = new InputStreamReader(
                        new FileInputStream("demo06.txt"))) {

        int c = 0;
        while ((c = in.read()) != -1) {
            System.out.println((char) c);
        }

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

2.public InputStreamReader(InputStream in,String charsetName):使用一个“字节流”和一个“编码表名称”构造一个转换流。

	public static void main(String[] args) {
	     //使用一个“字节流”和“UTF-8”构造一个转换流。使用UTF-8读取。
    try (InputStreamReader in = new InputStreamReader(
                        new FileInputStream("demo06.txt"),"UTF-8")) {
        int c = 0;
        while ((c = in.read()) != -1) {
            System.out.println((char) c);
        }

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

1.3.3.IO流_缓冲流:

分类:
字节流:
输出流:BufferedOutputStream
输入流:BufferedInputStream
字符流:
输出流:BufferedWriter
输入流:BufferedReader
作用:
磁盘一次可以读取多个字节/字符,如果一次只读取一个字节/字符降低程序的效率。所以字节流和字符流都支持一次读取多个字节符:
字节流:int read(byte[] byteArray)
字符流:int read(char[] charArray)
这个参数数组,就类似于一个“缓存区”,这样可以提高程序运行的效率。基于这种原因,Java类库中提供对字节流、字符流都提供了“自带缓存区”的“缓冲流”,可以提高程序的运行效率。
特点:
字节缓冲流:没有特有功能,只是内部提供了缓存区而已;

public static void main(String[] args) {
        long start = System.currentTimeMillis();
//        copy1();//273253 毫秒!
        //高效缓冲流复制
//        copy2();//9682 毫秒!
//        copy3();//6209 毫秒!
//        copy4();//4365 毫秒!
        long end = System.currentTimeMillis();
        System.out.println("复制时间:" + (end - start) + " 毫秒!");

    }
//高效缓冲流--一次读写一个字节数组
private static void copy4() {
    try (
            BufferedInputStream bufIn = new BufferedInputStream(
			new FileInputStream("d:\\douyu.exe"));
            BufferedOutputStream bufOut=new BufferedOutputStream(
			new FileOutputStream("e:\\douyu_copy4.exe"))) {
        //一次读写一个字节数组
        byte[] byteArray = new  byte[1024];
        int b = 0;
        while ((b = bufIn.read(byteArray)) != -1) {
            bufOut.write(byteArray,0,b);
        }
        System.out.println("复制完毕!");

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}
//基本字节流--一次读写一个字节数组
private static void copy3() {
    //基本字节流复制
    try (FileInputStream in = new FileInputStream("d:\\douyu.exe");
         FileOutputStream out = new FileOutputStream(
						"e:\\douyu_copy3.exe")
    ) {
        //一次读写一个字节数组
        byte[] byteArray = new byte[1024];
        int b = 0;
        while ((b = in.read(byteArray)) != -1) {
            out.write(byteArray,0,b);
        }
        System.out.println("完毕!");
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}
//高效字节流--一次读写一个字节
private static void copy2() {
    try (
            BufferedInputStream bufIn = new BufferedInputStream(
				new FileInputStream("d:\\douyu.exe"));
            BufferedOutputStream bufOut=new BufferedOutputStream(
				new FileOutputStream("e:\\douyu_copy2.exe"))) {
        //一次读写一个字节
        int b = 0;
        while ((b = bufIn.read()) != -1) {//从缓存区读
            bufOut.write(b);
        }
        System.out.println("复制完毕!");

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}
//基本字节流复制--一次读写一个字节
private static void copy1() {
    //基本字节流复制
    try (FileInputStream in = new FileInputStream("d:\\douyu.exe");
         FileOutputStream out = new FileOutputStream(
							"e:\\douyu_copy1.exe")
    ) {
        //一次读写一个字节
        int b = 0;
        while ((b = in.read()) != -1) {//从磁盘读
            out.write(b);
        }
        System.out.println("完毕!");
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

字符缓冲流:有

public static void main(String[] args) {
    try (BufferedWriter out = new BufferedWriter(
				new FileWriter("demo10.txt"));
         BufferedReader in = new BufferedReader(
				new FileReader("demo10.txt"))
        ) {
        //1.先输出
        out.write("床前明月光");
        out.newLine();//特有方法
        out.write("疑是地上霜");
        out.newLine();
        out.write("举头望明月");
        out.newLine();
        out.write("低头思故乡");

        out.flush();

        //2.再读取
        String row = null;
        while((row = in.readLine()) != null){//特有方法
            System.out.println(row);
        }


    } catch (IOException e) {
        e.printStackTrace();
    }
}
发布了12 篇原创文章 · 获赞 4 · 访问量 388

猜你喜欢

转载自blog.csdn.net/weixin_44079478/article/details/105379431