目录

Life in Flow

知不知,尚矣;不知知,病矣。
不知不知,殆矣。

X

Reader、Writer

IO 流体系图

IO 流体系图

Reader

 Reader 是输 ⼊字符流的 ⽗类,它是 ⼀个抽象类, 部分库不推荐使 ⽤ Reader/Writer。

常见方法

1//⼀个字符⼀个字符的读,只能⽤来操作⽂本(不能写图⽚ ⾳频 视频)
2int read()
3
4//从输⼊字符流中读取⼀定数量的字符,并将其存储在缓冲区数组cbuf中, 返回实际读取的字符 数,如果已经到达流末尾⽽没有可⽤的字节,则返回-1
5int read(char cbuf[])
6
7//关闭输⼊流并释放与该流关联的系统资源
8void close() throws IOException

FileReader

 用来读取字符 ⽂件的实现类。

 1/**
 2     * 读取中⽂显示出来, java运⾏时采⽤utf16编码,多数汉字占2个字节,⼀个char就够,少数占4个字节,需要两个char来表示
 3     */
 4    @Test
 5    public void readerCharArrayTesting() throws IOException {
 6        String filePath = "C:\\Users\\Ryzen-7-3800X\\Pictures\\Camera Roll\\test\\1\\1.txt";
 7        File file = new File(filePath);
 8        FileReader input = new FileReader(file);
 9
10        int size;
11        char[] ch = new char[1024];
12
13        while ((size = input.read(ch)) != -1){
14            System.out.print(new String(ch,0,size));
15        }
16        input.close();
17    }

Writer

 Writer 是输出字符流的 ⽗类,它是 ⼀个抽象类。

 1//直接将int型数据作为参数的话,是不会写⼊数字的,⽽是现将数字按照ascll码表转换为 相应的字符,然后写⼊
 2public void write(int c) throws IOException
 3
 4//要想实现数字和中⽂的写⼊,必须要⽤String为参数的Write
 5public void write(String str) throws IOException
 6
 7//将cbuf字符数组的⼀部分写⼊到流中,但能不能写len个字符取决于cbuf中是否有那么多
 8public abstract void write(char cbuf[], int off, int len) throws IOException;
 9
10//write是写到缓冲区中,可以认为是内存中,当缓冲区满时系统会⾃动将缓冲区的内容写⼊ ⽂件,但是⼀般还有⼀部分有可能会留在内存这个缓冲区中, 所以需要调⽤flush空缓冲区数据。 对⽐BufferWriter需要实时查表,效率低,其实缓冲区IO的各个都有,只不过很⼩被忽 略,OutputStream都有flush⽅法,看⼦类是否有重写
11void flush() throws IOException
12
13//关闭输⼊流并释放与该流关联的系统资源
14void close() throws IOException

FileWriter

 ⽤来写出字符 ⽂件的实现类。

 1//如果⽂件不存在,这会⾃动创建。如果⽂件存在,则会覆盖
 2public FileWriter(String fileName) throws IOException
 3
 4//如果⽂件不存在,这会⾃动创建。如果⽂件存在,则会覆盖
 5public FileWriter(File file) throws IOException
 6
 7//加⼊true参数,会实现对⽂件的续写,使⽤false则会实现对⽂件的覆盖
 8public FileWriter(String fileName, boolean append) throws IOException
 9
10//加⼊true参数,会实现对⽂件的续写,使⽤false则会实现对⽂件的覆盖
11public FileWriter(File file, boolean append) throws IOException

示例

 1/**
 2     * 传入int类型参数会查表 ASCII码  查表会消耗性能
 3     * 传入string类型参数 不会查表,直接写入,没有多余的性能开销
 4     * @throws IOException
 5     */
 6    @Test
 7    public void writerTesting() throws IOException {
 8        String filePath = "C:\\Users\\Ryzen-7-3800X\\Pictures\\Camera Roll\\test\\1\\2.txt";
 9        FileWriter writer = new FileWriter(filePath);
10        //FileWriter writer = new FileWriter(filePath,true); //追加
11        //FileWriter writer = new FileWriter(filePath,false); //覆盖
12
13        writer.write(23567); //小
14        writer.write(28404); //滴
15        writer.write(35838); //课
16        writer.write(22530); //堂
17        writer.write("23567"); //23567
18        writer.flush();
19        writer.close();
20    }

BufferedReader

 为了提 ⾼了单个字符读写的效率,进 ⾏字符批量的读写; 为了提 ⾼字符流读写的效率,引 ⼊了缓冲机制。
 当 BufferedReader 在读取 ⽂本 ⽂件时,会先尽量从 ⽂件中读 ⼊字符数据并放满缓冲 区,⽽之后若使 ⽤ read()⽅法,会先从缓冲区中进 ⾏读取。如果缓冲区数据不 ⾜,才会再从 ⽂ 件中读取。
构造函数

1BufferedReader(Reader in)
2
3//创建⼀个使⽤指定⼤⼩输⼊缓冲区的缓冲字符输⼊流。
4BufferedReader(Reader in, int sz)

常用 API

 1//判断此流是否已准备好被读取,依赖其他流,所以⼀般需要做判断
 2boolean ready()
 3
 4//读取单个字符
 5int read()
 6
 7//读取⼀部分字符到数组⾥⾯,从数组下标off处放置length⻓度的字符
 8int read(char[] cbuf, int off, int len)
 9
10//读取⼀整⾏⽂本⾏,返回⼀整⾏字符串,如果读到⾏尾了就返回null,注意返回的⼀⾏字符中不 包含换⾏符
11String readLine()
12
13//读取⼀整⾏⽂本⾏,返回⼀整⾏字符串,如果读到⾏尾了就返回null,注意返回的⼀⾏字符中不 包含换⾏符
14String readLine()

示例

 1/**
 2     * read()
 3     * @throws IOException
 4     */
 5    @Test
 6    public void bufferedWriterTesting() throws IOException {
 7        String filePath = "C:\\Users\\Ryzen-7-3800X\\Pictures\\Camera Roll\\test\\1\\1.txt";
 8        BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath));
 9        if (!bufferedReader.ready()) {
10            System.out.println("文件流暂时无法读取");
11            return;
12        }
13
14        int size;
15        char[] cbuf = new char[1024];
16        while ((size = bufferedReader.read(cbuf, 0, cbuf.length)) != -1) {
17            System.out.println(new String(cbuf,0,size));
18        }
19    }
20
21    /**
22     * readLine()
23     * @throws IOException
24     */
25    @Test
26    public void bufferedWriterReadlineTesting() throws IOException {
27        String filePath = "C:\\Users\\Ryzen-7-3800X\\Pictures\\Camera Roll\\test\\1\\1.txt";
28        BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath));
29        if (!bufferedReader.ready()) {
30            System.out.println("文件流暂时无法读取");
31            return;
32        }
33
34        String str = "";
35        while ((str = bufferedReader.readLine()) != null) {
36            System.out.println(str);
37        }
38        bufferedReader.close();
39    }

BufferedWriter

 写 ⼊的数据并不会先输出到 ⽬的地,⽽是先存储 ⾄缓冲区中。如果缓冲区中的数据满 了,才会 ⼀次对 ⽬的地进 ⾏写出。
构造函数

1BufferedWriter(Writer out)
2
3BufferedWriter(Writer out, int sz)

常用 API

 1//写⼊⼀个字符
 2void write(int c)
 3
 4//写⼊字符数组的⼀部分,通过off和len控制。
 5void write(char[] cbuf, int off, int len)
 6
 7//写⼊字符串的⼀部分,通过off和len控制。
 8void write(String s, int off, int len)
 9
10//写如⼀个换⾏符合
11void newLine()
12
13//关闭输⼊流并释放与该流关联的系统资源
14void close()
15
16//write是写到缓冲区中,可以认为是内存中,当缓冲区满时系统会⾃动将缓冲区的内容 写⼊⽂件,但是⼀般还有⼀部分有可能会留在内存这个缓冲区中, 所以需要调⽤flush空缓 冲区数据。
17void flush()

示例

 1@Test
 2    public void BufferedWriterTest() throws IOException {
 3        String filePath = "C:\\Users\\Ryzen-7-3800X\\Pictures\\Camera Roll\\test\\1\\2.txt";
 4        BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filePath));
 5
 6        //写入一个字符
 7        char ch = '你';
 8        bufferedWriter.write(ch);
 9
10        //写入一个字符数组
11        String strArray = "好!北京欢迎你!";
12        bufferedWriter.write(strArray.toCharArray(),0,strArray.length());
13
14        //写入一个换行符
15        bufferedWriter.newLine();
16
17        //写入一个字符串
18        String newStr = "哈哈哈!";
19        bufferedWriter.write(newStr);
20
21        //关闭资源
22        bufferedWriter.close();
23
24        //你好!北京欢迎你!
25        //哈哈哈!
26    }

InputStreamReader

 计算机存储的单位是字节,从持久设备读取到程序中是解码,从程序写到持久设备中是编码 不管是编码还是解码,不同字符集编解码成 字符 需要不同的个数,因此字节流读取容易出错,⽐ 如乱码。
 需要 ⼀个流,把字节流读取的字节进 ⾏缓冲后,在通过字符集解码成字符返回。

InputStreamReader(继承 Reader)
将字节流转换为字符流, 字节流通向字符流的桥梁,如果不指定字符集编码,则解码过程 将使 ⽤平台默认的字符编码,如:UTF-8
 ⽂本 ⽂件存储是 A 编码,然后如果以 B 编码进 ⾏读取则会乱码

构造函数

1//使⽤系统默认编码集
2public InputStreamReader(InputStream in)
3
4//指定指定编码集创建对象
5public InputStreamReader(InputStream in, String charsetName)

常用 API

 1//读取单个字符
 2int read()
 3
 4//读取⼀部分字符到数组⾥⾯,从数组下标off处放置length⻓度的字符
 5int read(char[] cbuf, int off, int len)
 6
 7//将读取到的字符存到数组中,返回读取的字符数
 8int read(char []cbuf)
 9
10//关闭流释放资源
11void close()

示例

 1@Test
 2    public void inputStreamReadTesting() throws IOException {
 3        String filePath = "C:\\Users\\Ryzen-7-3800X\\Pictures\\Camera Roll\\test\\1\\1.txt";
 4        //读取字节流
 5        InputStream inputStream = new FileInputStream(filePath);
 6
 7        //字节流向字符流转换: 转换之后变为InputStreamReader  属于 字符流
 8        InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "UTF-8");//默认解码采用UTF-8
 9
10        //字符流缓冲区对 InputStreamReader 进行包装,提高性能
11        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
12
13        String line;
14
15        while ((line = bufferedReader.readLine()) != null) {
16            System.out.println(line);
17        }
18        inputStream.close();
19        bufferedReader.close();
20    }

OutputStreamWriter

将字符流转换为字节流(看源码解释), 字符流通向字节流的桥梁,如果不指定字符集编码,则编码过程将使 ⽤平台默认的字符编码,如:GBK

构造函数

1//使⽤系统默认编码集
2public OutputStreamWriter(OutputStream out)
3
4//指定指定编码集创建对象
5public OutputStreamWriter(OutputStream out, String charsetName)

常用 API

 1//写⼊⼀个字符
 2void write(int c)
 3
 4//写⼊字符数组的⼀部分,通过off和len控制。
 5void write(char[] cbuf, int off, int len)
 6
 7//写⼊字符数组的⼀部分,通过off和len控制。
 8void write(String s, int off, int len)
 9
10//写如⼀个换⾏符合
11void newLine()
12
13//关闭输⼊流并释放与该流关联的系统资源
14void close()
15
16//write是写到缓冲区中,可以认为是内存中,当缓冲区满时系统会⾃动将缓冲区的内容 写⼊⽂件,但是⼀般还有⼀部分有可能会留在内存这个缓冲区中, 所以需要调⽤flush空缓 冲区数据。
17void flush()

示例

 1@Test
 2    public void outputStreamReadTesting() throws IOException {
 3        String filePath = "C:\\Users\\Ryzen-7-3800X\\Pictures\\Camera Roll\\test\\1\\2.txt";
 4        
 5        //写入字节流
 6        OutputStream outputStream = new FileOutputStream(filePath);
 7        
 8        //将写入字符流转成写入字节流
 9        OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream,"UTF-8");//默认的编码是UTF-8
10
11        //采用Buffered包装写入字符流
12        BufferedWriter bufferedWriter = new BufferedWriter(outputStreamWriter);
13
14        String str = "北京欢迎你! Welcome to Bei Jing! ";
15
16        bufferedWriter.write(str);
17        bufferedWriter.newLine();
18        bufferedWriter.write("哈哈哈!~");
19        bufferedWriter.flush();
20        bufferedWriter.close();
21
22        //北京欢迎你! Welcome to Bei Jing!
23        //哈哈哈!~
24    }

作者:Soulboy