概念

BufferedReader:是一个从字符输入流中读取文本的类。它提供了一个缓冲区,可以一次性读取大量数据,从而减少实际读取操作的次数,提高读取效率。

BufferedWriter:是一个将文本写入字符输出流的类。它提供了一个缓冲区,可以一次性写入大量数据,从而减少实际写入操作的次数,提高写入效率。

主要构造方法

BufferedReader

BufferedReader(Reader in): 创建一个使用默认大小输入缓冲区的缓冲字符输入流。

BufferedReader(Reader in, int sz): 创建一个使用指定大小输入缓冲区的缓冲字符输入流。

BufferedWriter

BufferedWriter(Writer out): 创建一个使用默认大小输出缓冲区的缓冲字符输出流。

BufferedWriter(Writer out, int sz): 创建一个使用指定大小输出缓冲区的缓冲字符输出流。

public static void main(String[] args) throws IOException {

        // BufferedWriter(Writer out): 创建一个使用默认大小输出缓冲区的缓冲字符输出流。
        BufferedReader br1 = new BufferedReader(new FileReader("aaa.txt"));

        //BufferedReader(Reader in, int sz): 创建一个使用指定大小输入缓冲区的缓冲字符输入流。
        BufferedReader br2 = new BufferedReader(new FileReader("aaa.txt"),8000);

        //BufferedWriter(Writer out): 创建一个使用默认大小输出缓冲区的缓冲字符输出流。
        BufferedWriter bw1 = new BufferedWriter(new FileWriter("bbb.txt"));

        //BufferedWriter(Writer out, int sz): 创建一个使用指定大小输出缓冲区的缓冲字符输出流。
        BufferedWriter bw2 = new BufferedWriter(new FileWriter("bbb.txt"),8000);
    }

缓冲区大小

BufferedReader和BufferedWriter的内部缓冲区大小可以通过构造函数来设置。如果不显式设置,默认大小通常是8192字节。

主要方法

BufferedReader

  • read(): 读取单个字符并返回。如果已到达流的末尾,则返回-1。
  • read(char[] cbuf, int off, int len): 将字符读入数组的一部分。返回读取的字符数,或者在流的末尾返回-1。
  • readLine(): 读取一个文本行,返回一个包含行内容的字符串,不包含任何行终止符。如果已到达流的末尾,则返回null。
  • ready(): 判断输入流是否准备好进行读取,返回布尔值。
  • close(): 关闭流并释放与之关联的所有资源。
public static void main(String[] args) {
        //read()
        try (BufferedReader br = new BufferedReader(new FileReader("/home/utarn/桌面/aaa.txt"))) {
            int c;
            //read()
            //读取单个字符并返回其整数表示,如果已到达流的末尾,则返回-1。
            while ((c = br.read())!=-1){
                System.out.print((char)c);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        //read(char[] cbuf, int off, int len)
        try (BufferedReader br = new BufferedReader(new FileReader("/home/utarn/桌面/aaa.txt"))) {
            char[] buffer = new char[2];
            int numRead;
            //read(char[] cbuf, int off, int len)
            //将字符读入数组的一部分,返回读取的字符数,或者在流的末尾返回-1。
            if ((numRead = br.read(buffer, 0, buffer.length)) != -1) {
                System.out.print(new String(buffer, 0, numRead));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println();

        //readLine()
        try (BufferedReader br = new BufferedReader(new FileReader("/home/utarn/桌面/aaa.txt"))) {
            String line;
            //readLine()
            //读取一个文本行,返回一个包含行内容的字符串,不包含任何行终止符。如果已到达流的末尾,则返回null。
            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        //ready()
        //判断输入流是否准备好进行读取,返回布尔值。
        try (BufferedReader br = new BufferedReader(new FileReader("/home/utarn/桌面/aaa.txt"))) {
            while (br.ready()) {
                System.out.println(br.readLine());
            } 
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

BufferedWriter

  • write(int c): 写入单个字符。
  • write(char[] cbuf, int off, int len): 写入字符数组的一部分。
  • write(String s, int off, int len): 写入字符串的一部分。
  • newLine(): 写入一个行分隔符。
  • flush(): 刷新缓冲区,将缓冲区内容写入输出流。
  • close(): 关闭流,并刷新任何缓冲的输出。
public static void main(String[] args) {
        //write(int c)
        //写入单个字符。
        try (BufferedWriter bw = new BufferedWriter(new FileWriter("/home/utarn/桌面/bbb.txt"))) {
            bw.write('H');
            bw.write('e');
            bw.write('l');
            bw.write('l');
            bw.write('o');
        } catch (IOException e) {
            e.printStackTrace();
        }

        //write(char[] cbuf, int off, int len)
        //写入字符数组的一部分。
        try (BufferedWriter bw = new BufferedWriter(new FileWriter("/home/utarn/桌面/bbb.txt"))) {
            char[] buffer = "Hello, World!".toCharArray();
            bw.write(buffer, 0, buffer.length);
        } catch (IOException e) {
            e.printStackTrace();
        }

        //write(String s, int off, int len)
        //写入字符串的一部分。
        try (BufferedWriter bw = new BufferedWriter(new FileWriter("/home/utarn/桌面/bbb.txt"))) {
            String str = "Hello, World! write(String s, int off, int len)";
            bw.write(str, 0, str.length());
        } catch (IOException e) {
            e.printStackTrace();
        }

        //newLine() 写入一个行分隔符。
        //flush() 刷新缓冲区,将缓冲区内容写入输出流。
        try (BufferedWriter bw = new BufferedWriter(new FileWriter("/home/utarn/桌面/bbb.txt"))) {
            bw.write("Hello, World!");
            bw.newLine();     // 空一行
            bw.write("newLine()");
            bw.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

try-with-resources

在Java中,try-with-resources语句是用于自动关闭实现了java.lang.AutoCloseable接口(包括实现了java.io.Closeable接口)的资源(如文件、流、网络连接等)的结构化方式。它可以确保在使用完资源后自动关闭它们,避免资源泄漏。

示例代码解释

我们可以使用try-with-resources语句来自动管理资源,确保它们在使用完毕后正确关闭,即使在发生异常的情况下。

下面是一个使用try-with-resources语句的例子,展示如何使用BufferedWriter写入文件,并确保资源在使用后自动关闭。

package org.example;

import java.io.*;
public class Buffer {
    public static void main(String[] args) {
        try (BufferedWriter bw = new BufferedWriter(new FileWriter("/home/utarn/桌面/bbb.txt"))) {
            bw.write("Hello, World!");
            bw.newLine();     // 空一行
            bw.write("newLine()");
            bw.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

关键点

  1. 自动关闭资源:在try块中声明的资源(在此例中为BufferedWriter)在try块结束时会自动关闭,无需显式调用close()方法。这是在try块退出时,无论是正常退出还是由于异常退出,都会执行的。
  2. 减少冗余代码:try-with-resources语句减少了手动管理资源的冗余代码,使代码更简洁和易读。
  3. 异常处理:如果在使用资源的过程中抛出异常,try-with-resources语句仍会确保资源被关闭。这是通过自动调用资源的close()方法来实现的。

flush()方法的作用

虽然try-with-resources会在关闭BufferedWriter时自动调用flush(),但有时你可能希望在某些时刻强制将缓冲区中的数据写入文件。示例:

package org.example;

import java.io.*;
public class Buffer {
    public static void main(String[] args) {
        try (BufferedWriter bw = new BufferedWriter(new FileWriter("/home/utarn/桌面/bbb.txt"))) {
            bw.write("Hello, World!");
            bw.newLine();     // 空一行
            bw.write("newLine()");
            bw.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

在上述示例中,flush()方法会强制将缓冲区中的内容立即写入文件,这在需要确保数据在某个特定时刻被写入时是有用的,例如在实时日志记录或系统状态持久化时。

总结

  1. try-with-resources语句:简化资源管理,确保资源在使用后自动关闭。
  2. 自动调用close():try-with-resources会自动调用资源的close()方法,即使发生异常。
  3. 显式调用flush():在需要立即写入数据时,可以显式调用flush()方法,尽管在资源关闭时会自动刷新缓冲区。

注意事项

  1. 缓冲区大小:默认缓冲区大小一般是8KB,具体大小可以根据需求调整。如果进行大量小数据的读写操作,适当增大缓冲区大小可以提高性能。
  2. 资源管理:在使用BufferedReader和BufferedWriter时,务必在操作完成后关闭流,以释放系统资源。使用try-with-resources语句可以自动关闭流。
  3. 线程安全:BufferedReader和BufferedWriter不是线程安全的,如果多个线程同时访问同一个流,可能会导致数据不一致。可以使用适当的同步机制来保证线程安全。
  4. 高效读写:为了高效地读取和写入数据,缓冲机制是关键。通过减少实际I/O操作的次数,BufferedReader和BufferedWriter提供了显著的性能提升,特别是在处理大文件或频繁读写的场景下。

转载自开思通智网:https://www.opensnn.com/os/article/10000859


失望的双杠_eJN3LI
1 声望0 粉丝

引用和评论

0 条评论