目录

Life in Flow

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

X

Reader、Writer

IO 流体系图

IO流体系图

Reader

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

常见方法

//⼀个字符⼀个字符的读,只能⽤来操作⽂本(不能写图⽚ ⾳频 视频)
int read()

//从输⼊字符流中读取⼀定数量的字符,并将其存储在缓冲区数组cbuf中, 返回实际读取的字符 数,如果已经到达流末尾⽽没有可⽤的字节,则返回-1
int read(char cbuf[])

//关闭输⼊流并释放与该流关联的系统资源
void close() throws IOException

FileReader

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

/**
     * 读取中⽂显示出来, java运⾏时采⽤utf16编码,多数汉字占2个字节,⼀个char就够,少数占4个字节,需要两个char来表示
     */
    @Test
    public void readerCharArrayTesting() throws IOException {
        String filePath = "C:\\Users\\Ryzen-7-3800X\\Pictures\\Camera Roll\\test\\1\\1.txt";
        File file = new File(filePath);
        FileReader input = new FileReader(file);

        int size;
        char[] ch = new char[1024];

        while ((size = input.read(ch)) != -1){
            System.out.print(new String(ch,0,size));
        }
        input.close();
    }

Writer

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

//直接将int型数据作为参数的话,是不会写⼊数字的,⽽是现将数字按照ascll码表转换为 相应的字符,然后写⼊
public void write(int c) throws IOException

//要想实现数字和中⽂的写⼊,必须要⽤String为参数的Write
public void write(String str) throws IOException

//将cbuf字符数组的⼀部分写⼊到流中,但能不能写len个字符取决于cbuf中是否有那么多
public abstract void write(char cbuf[], int off, int len) throws IOException;

//write是写到缓冲区中,可以认为是内存中,当缓冲区满时系统会⾃动将缓冲区的内容写⼊ ⽂件,但是⼀般还有⼀部分有可能会留在内存这个缓冲区中, 所以需要调⽤flush空缓冲区数据。 对⽐BufferWriter需要实时查表,效率低,其实缓冲区IO的各个都有,只不过很⼩被忽 略,OutputStream都有flush⽅法,看⼦类是否有重写
void flush() throws IOException

//关闭输⼊流并释放与该流关联的系统资源
void close() throws IOException

FileWriter

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

//如果⽂件不存在,这会⾃动创建。如果⽂件存在,则会覆盖
public FileWriter(String fileName) throws IOException

//如果⽂件不存在,这会⾃动创建。如果⽂件存在,则会覆盖
public FileWriter(File file) throws IOException

//加⼊true参数,会实现对⽂件的续写,使⽤false则会实现对⽂件的覆盖
public FileWriter(String fileName, boolean append) throws IOException

//加⼊true参数,会实现对⽂件的续写,使⽤false则会实现对⽂件的覆盖
public FileWriter(File file, boolean append) throws IOException

示例

/**
     * 传入int类型参数会查表 ASCII码  查表会消耗性能
     * 传入string类型参数 不会查表,直接写入,没有多余的性能开销
     * @throws IOException
     */
    @Test
    public void writerTesting() throws IOException {
        String filePath = "C:\\Users\\Ryzen-7-3800X\\Pictures\\Camera Roll\\test\\1\\2.txt";
        FileWriter writer = new FileWriter(filePath);
        //FileWriter writer = new FileWriter(filePath,true); //追加
        //FileWriter writer = new FileWriter(filePath,false); //覆盖

        writer.write(23567); //小
        writer.write(28404); //滴
        writer.write(35838); //课
        writer.write(22530); //堂
        writer.write("23567"); //23567
        writer.flush();
        writer.close();
    }

BufferedReader

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

BufferedReader(Reader in)

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

常用 API

//判断此流是否已准备好被读取,依赖其他流,所以⼀般需要做判断
boolean ready()

//读取单个字符
int read()

//读取⼀部分字符到数组⾥⾯,从数组下标off处放置length⻓度的字符
int read(char[] cbuf, int off, int len)

//读取⼀整⾏⽂本⾏,返回⼀整⾏字符串,如果读到⾏尾了就返回null,注意返回的⼀⾏字符中不 包含换⾏符
String readLine()

//读取⼀整⾏⽂本⾏,返回⼀整⾏字符串,如果读到⾏尾了就返回null,注意返回的⼀⾏字符中不 包含换⾏符
String readLine()

示例

/**
     * read()
     * @throws IOException
     */
    @Test
    public void bufferedWriterTesting() throws IOException {
        String filePath = "C:\\Users\\Ryzen-7-3800X\\Pictures\\Camera Roll\\test\\1\\1.txt";
        BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath));
        if (!bufferedReader.ready()) {
            System.out.println("文件流暂时无法读取");
            return;
        }

        int size;
        char[] cbuf = new char[1024];
        while ((size = bufferedReader.read(cbuf, 0, cbuf.length)) != -1) {
            System.out.println(new String(cbuf,0,size));
        }
    }

    /**
     * readLine()
     * @throws IOException
     */
    @Test
    public void bufferedWriterReadlineTesting() throws IOException {
        String filePath = "C:\\Users\\Ryzen-7-3800X\\Pictures\\Camera Roll\\test\\1\\1.txt";
        BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath));
        if (!bufferedReader.ready()) {
            System.out.println("文件流暂时无法读取");
            return;
        }

        String str = "";
        while ((str = bufferedReader.readLine()) != null) {
            System.out.println(str);
        }
        bufferedReader.close();
    }

BufferedWriter

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

BufferedWriter(Writer out)

BufferedWriter(Writer out, int sz)

常用 API

//写⼊⼀个字符
void write(int c)

//写⼊字符数组的⼀部分,通过off和len控制。
void write(char[] cbuf, int off, int len)

//写⼊字符串的⼀部分,通过off和len控制。
void write(String s, int off, int len)

//写如⼀个换⾏符合
void newLine()

//关闭输⼊流并释放与该流关联的系统资源
void close()

//write是写到缓冲区中,可以认为是内存中,当缓冲区满时系统会⾃动将缓冲区的内容 写⼊⽂件,但是⼀般还有⼀部分有可能会留在内存这个缓冲区中, 所以需要调⽤flush空缓 冲区数据。
void flush()

示例

@Test
    public void BufferedWriterTest() throws IOException {
        String filePath = "C:\\Users\\Ryzen-7-3800X\\Pictures\\Camera Roll\\test\\1\\2.txt";
        BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filePath));

        //写入一个字符
        char ch = '你';
        bufferedWriter.write(ch);

        //写入一个字符数组
        String strArray = "好!北京欢迎你!";
        bufferedWriter.write(strArray.toCharArray(),0,strArray.length());

        //写入一个换行符
        bufferedWriter.newLine();

        //写入一个字符串
        String newStr = "哈哈哈!";
        bufferedWriter.write(newStr);

        //关闭资源
        bufferedWriter.close();

        //你好!北京欢迎你!
        //哈哈哈!
    }

InputStreamReader

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

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

构造函数

//使⽤系统默认编码集
public InputStreamReader(InputStream in)

//指定指定编码集创建对象
public InputStreamReader(InputStream in, String charsetName)

常用 API

//读取单个字符
int read()

//读取⼀部分字符到数组⾥⾯,从数组下标off处放置length⻓度的字符
int read(char[] cbuf, int off, int len)

//将读取到的字符存到数组中,返回读取的字符数
int read(char []cbuf)

//关闭流释放资源
void close()

示例

@Test
    public void inputStreamReadTesting() throws IOException {
        String filePath = "C:\\Users\\Ryzen-7-3800X\\Pictures\\Camera Roll\\test\\1\\1.txt";
        //读取字节流
        InputStream inputStream = new FileInputStream(filePath);

        //字节流向字符流转换: 转换之后变为InputStreamReader  属于 字符流
        InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "UTF-8");//默认解码采用UTF-8

        //字符流缓冲区对 InputStreamReader 进行包装,提高性能
        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

        String line;

        while ((line = bufferedReader.readLine()) != null) {
            System.out.println(line);
        }
        inputStream.close();
        bufferedReader.close();
    }

OutputStreamWriter

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

构造函数

//使⽤系统默认编码集
public OutputStreamWriter(OutputStream out)

//指定指定编码集创建对象
public OutputStreamWriter(OutputStream out, String charsetName)

常用 API

//写⼊⼀个字符
void write(int c)

//写⼊字符数组的⼀部分,通过off和len控制。
void write(char[] cbuf, int off, int len)

//写⼊字符数组的⼀部分,通过off和len控制。
void write(String s, int off, int len)

//写如⼀个换⾏符合
void newLine()

//关闭输⼊流并释放与该流关联的系统资源
void close()

//write是写到缓冲区中,可以认为是内存中,当缓冲区满时系统会⾃动将缓冲区的内容 写⼊⽂件,但是⼀般还有⼀部分有可能会留在内存这个缓冲区中, 所以需要调⽤flush空缓 冲区数据。
void flush()

示例

@Test
    public void outputStreamReadTesting() throws IOException {
        String filePath = "C:\\Users\\Ryzen-7-3800X\\Pictures\\Camera Roll\\test\\1\\2.txt";
        
        //写入字节流
        OutputStream outputStream = new FileOutputStream(filePath);
        
        //将写入字符流转成写入字节流
        OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream,"UTF-8");//默认的编码是UTF-8

        //采用Buffered包装写入字符流
        BufferedWriter bufferedWriter = new BufferedWriter(outputStreamWriter);

        String str = "北京欢迎你! Welcome to Bei Jing! ";

        bufferedWriter.write(str);
        bufferedWriter.newLine();
        bufferedWriter.write("哈哈哈!~");
        bufferedWriter.flush();
        bufferedWriter.close();

        //北京欢迎你! Welcome to Bei Jing!
        //哈哈哈!~
    }

作者:Soulboy