BufferedReader和BufferedWriter

概念

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

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

主要构造方法

BufferedReader

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

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

BufferedWriter

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

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

java 复制代码
 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(): 关闭流并释放与之关联的所有资源。
java 复制代码
 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(): 关闭流,并刷新任何缓冲的输出。
java 复制代码
 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写入文件,并确保资源在使用后自动关闭。

java 复制代码
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(),但有时你可能希望在某些时刻强制将缓冲区中的数据写入文件。示例:

java 复制代码
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提供了显著的性能提升,特别是在处理大文件或频繁读写的场景下。

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

相关推荐
无尽的沉默几秒前
SpringBoot整合Redis
spring boot·redis·后端
摸鱼的春哥7 分钟前
春哥的Agent通关秘籍07:5分钟实现文件归类助手【实战】
前端·javascript·后端
Victor35623 分钟前
MongoDB(2)MongoDB与传统关系型数据库的主要区别是什么?
后端
JaguarJack24 分钟前
PHP 应用遭遇 DDoS 攻击时会发生什么 从入门到进阶的防护指南
后端·php·服务端
BingoGo25 分钟前
PHP 应用遭遇 DDoS 攻击时会发生什么 从入门到进阶的防护指南
后端
Victor35626 分钟前
MongoDB(3)什么是文档(Document)?
后端
牛奔2 小时前
Go 如何避免频繁抢占?
开发语言·后端·golang
想用offer打牌7 小时前
MCP (Model Context Protocol) 技术理解 - 第二篇
后端·aigc·mcp
KYGALYX9 小时前
服务异步通信
开发语言·后端·微服务·ruby
掘了9 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结