四、缓冲输入输出流BufferedReader/BufferedWriter解析与使用

在Java的 的BufferedReader类,java.io.BufferedReader提供缓冲为您的JavaReader实例。缓冲可以大大加快 IO。Reader不是一次从底层读取一个字符,而是一次BufferedReader读取一个更大的块(数组)。这通常要快得多,特别是对于磁盘访问和更大的数据量。
BufferedReader类似于BufferedInputStream 但它们并不完全相同。之间的主要区别BufferedReader和 BufferedInputStream是BufferedReader读取字符(文本),而 BufferedInputStream读出的原始字节。
JavaBufferedReader类是Java Reader类的子类,因此您可以在BufferedReader任何Reader需要的地方使用 。

一、BufferedReader

1.1 BufferedReader 示例

要将缓冲添加到 JavaReader实例,只需将其包装在BufferedReader. 这是它的外观:

 BufferedReader reader = new BufferedReader(new FileReader("C:\\IO_Test\\data.txt"));
        String dataLine=null;
        while((dataLine=reader.readLine())!=null){
            System.out.println(dataLine);
        }
                      

此示例创建一个BufferedReader包装的FileReader。在 BufferedReader将读取从字符块FileReader(通常为 char数组)。read()因此从这个内部数组返回的每个字符返回。当数组被完全读取时,BufferedReader将新的数据块读入数组等。

1.2 BufferedReader 缓冲区大小

您可以设置缓冲区大小以供BufferedReader. 您提供大小作为构造函数参数,如下所示:

int bufferSize = 8 * 1024; 
BufferedReader bufferedReader = new BufferedReader( 
                      new FileReader("c:\\data\\input-file.txt"), 
                      bufferSize 
);

此示例将内部缓冲区设置为 8 KB。最好使用 1024 字节倍数的缓冲区大小。这对于硬盘等中的大多数内置缓冲效果最佳。

除了向Reader实例添加缓冲之外,Java 的BufferedReader行为与Reader. 虽然BufferedReader有一个额外的方法,readLine()方法。如果您需要一次读取输入一行,此方法会很方便。下面是一个BufferedReader readLine() 例子:
字符串行 = bufferedReader.readLine();
该readLine()方法将返回从BufferedReader. 如果没有更多数据要从底层读取Reader,则BufferedReader’sreadLine()方法将返回null。

1.3 从 BufferedReader 读取字符数组

JavaBufferedReader类还有一个read()方法,它接受一个char数组作为参数,以及一个起始偏移量和长度。该char阵列是其中read() 方法将读取的字符进。offset 参数是char数组中read() 方法应该开始读入的位置。长度参数是read()方法应该char从偏移量和向前读入数组的字符数。以下是char使用 Java将字符数组读入数组的示例BufferedReader:

Reader reader = 
    new BufferedReader( 
        new FileReader("/path/to/file/thefile.txt")); 

char[] theChars = new char[128]; 

int charsRead = reader.read(theChars, 0, theChars.length); 
while(charsRead != -1) { 
    System.out.println(new String(theChars, 0, charsRead)); 
    charsRead = reader.read(theChars, 0, theChars.length); 
}

该read(char[], offset, length)方法返回读入char数组的字符数,如果在 中没有更多字符要读取BufferedReader,例如如果BufferedReader已到达连接到的文件末尾,则返回 -1 。

1.4 从 BufferedReader 读取一行

JavaBufferedReader有一个名为 的特殊读取方法readLine(),它从BufferedReader的内部缓冲区读取整行文本。该readLine()方法返回一个String. 如果没有更多行要从 中读取,则BufferedReader该readLine()方法返回null。下面是一个使用 Java 逐行读取文本文件的示例BufferedReader:

BufferedReader bufferedReader = 
    new BufferedReader( 
        new FileReader("/path/to/file/thefile.txt")); 

字符串行 = bufferedReader.readLine(); 
while(line != null) { 
    System.out.println(line); 
    line = bufferedReader.readLine(); 
}

1.5 读取性能

一次读取一个字符数组比一次从 Java 中读取一个字符要快Reader。但是,由于BufferedReader已经进行了一些内部缓冲,因此差异很可能不像不Reader使用缓冲的a 那样显着。不过,您很可能仍会看到细微的差异。

1.6 跳过字符

JavaBufferedReader类有一个名为的方法skip(),可用于跳过输入中您不想读取的多个字符。您将要跳过的字符数作为参数传递给skip()方法。以下是从 Java 中跳过字符的示例BufferedReader:

long charsSkipped = bufferedReader.skip(24);

这个例子告诉 JavaBufferedReader跳过BufferedReader. 该skip()方法返回跳过的实际字符数。在大多数情况下,这将与您请求跳过的数字相同,但如果剩余的字符BufferedReader 数少于您请求跳过的数字,则返回的跳过字符数可能小于您请求跳过的字符数。

1.8 可重用的 BufferedReader

标准 Java 的弱点之一BufferedReader是它只能使用一次。一旦你关闭它,它就不再可用。如果需要读取大量文件或网络流,则必须为要读取的每个文件或网络流创建一个新的 BufferedReader。这意味着您正在创建一个新对象,更重要的是,创建一个新的 char 数组,该数组用作 BufferedReader 内的缓冲区。如果读取的文件或流的数量很高,并且它们被快速读取,这会给 Java 垃圾收集器带来压力。

另一种方法是创建一个可重用的 BufferedReader ,您可以在其中替换基础 source Reader,因此可以重用 BufferedReader 及其内部字节数组缓冲区。为了省去您的麻烦,我创建了这样一个ReusableBufferedReader,并在本教程的后面包含了它的代码。首先,我想向您展示如何使用它ReusableBufferedReader。

1.8.1 创建一个 ReusableBufferedReader

首先,您需要创建一个ReusableBufferedReader. 以下是如何创建一个示例 ReusableBufferedReader:

ReusableBufferedReader reusableBufferedReader = 
    new ReusableBufferedReader(new char[1024 * 1024]);

此示例创建一个ReusableBufferedReader2 MB 字符数组(1024 * 1024 个字符,1 个字符 = 2 个字节)作为其内部缓冲区。

1.8.2 设置来源

创建了 一个后,ReusableBufferedReader您需要将其设置Reader 为用作基础数据源。以下是Reader设置源的方法 ReusableBufferedReader:

FileReader reader = new FileReader("/mydata/somefile.txt"); 
reusableBufferedReader.setSource(reader);

该setSource()方法实际上返回对 的引用ReusableBufferedReader,因此您实际上可以ReusableBufferedReader在单个指令中创建一个并设置源:

ReusableBufferedReader reusableBufferedReader = 
    new ReusableBufferedReader(new byte[1024 * 1024]) 
        .setSource(new FileReader("/mydata/somefile.txt"));

1.8.3 重用 ReusableBufferedReader

使用完后,ReusableBufferedReader您需要关闭它。关闭它只会关闭底层源Reader。关闭 a 后,ReusableBufferedReader 您可以再次使用它,只需Reader在其上设置新源即可。这是重用 a 的样子ReusableBufferedReader:

reusableBufferedReader.setSource(new FileReader("/mydata/file-1.txt")); 
//从 ReusableBufferedReader 读取数据
reusableBufferedReader.close(); 
reusableBufferedReader.setSource(new FileReader("/mydata/file-1.txt")); 
//从 ReusableBufferedReader 读取数据
reusableBufferedReader.close();

1.8.4 ReusableBufferedReader 代码

这是ReusableBufferedReader上面描述的代码。请注意,此实现仅覆盖它扩展的类的read()和read(char[] dest, int offset, int length)方法Reader。其余的 Reader方法已被省略以保持代码更短 - 但您可以在需要时自己实现它们。

import java.io.IOException;
import java.io.Reader;

public class ReusableBufferedReader extends Reader {

    private char[]      buffer = null;
    private int         writeIndex = 0;
    private int         readIndex  = 0;
    private boolean     endOfReaderReached = false;

    private Reader      source = null;


    public ReusableBufferedReader(char[] buffer) {
        this.buffer = buffer;
    }

    public ReusableBufferedReader setSource(Reader source){
        this.source = source;
        this.writeIndex = 0;
        this.readIndex  = 0;
        this.endOfReaderReached = false;
        return this;
    }

    @Override
    public int read() throws IOException {
        if(endOfReaderReached) {
            return -1;
        }

        if(readIndex == writeIndex) {
            if(writeIndex == buffer.length) {
                this.writeIndex = 0;
                this.readIndex  = 0;
            }
            //data should be read into buffer.
            int bytesRead = readCharsIntoBuffer();
            while(bytesRead == 0) {
                //continue until you actually get some bytes !
                bytesRead = readCharsIntoBuffer();
            }

            //if no more data could be read in, return -1;
            if(bytesRead == -1) {
                return -1;
            }
        }

        return 65535 & this.buffer[readIndex++];
    }

    @Override
    public int read(char[] dest, int offset, int length) throws IOException {
        int charsRead = 0;
        int data = 0;
        while(data != -1 && charsRead < length){
            data = read();
            if(data == -1) {
                endOfReaderReached = true;
                if(charsRead == 0){
                    return -1;
                }
                return charsRead;
            }
            dest[offset + charsRead] = (char) (65535 & data);
            charsRead++;
        }
        return charsRead;
    }

    private int readCharsIntoBuffer() throws IOException {
        int charsRead = this.source.read(this.buffer, this.writeIndex, this.buffer.length - this.writeIndex);
        writeIndex += charsRead;
        return charsRead;
    }

    @Override
    public void close() throws IOException {
        this.source.close();
    }
}

二、BufferedWriter 输出流

在Java的 的BufferedWriter类,java.io.BufferedWriter提供缓冲,以 Writer实例。缓冲可以大大加快 IO。不是一次向网络或磁盘写入一个字符,而是一次BufferedWriter写入一个更大的块。这通常要快得多,特别是对于磁盘访问和更大的数据量。
JavaBufferedWriter是Java Writer子类,因此可以在Writer需要的任何地方使用。

2.1 Java BufferedWriter 示例

将缓冲添加到一个Writer简单的将它包装在一个 Java 中BufferedWriter。这是它的外观:

BufferedWriter bufferedWriter = 
    new BufferedWriter(new FileWriter("c:\\data\\output-file.txt"));

此示例创建了BufferedWriter将字符写入 a 的 a FileWriter。很简单,不是吗?

2.2 write(char[]) 写char数组

JavaBufferedWriter还有一种write(char[])方法可以将字符数组写入其内部缓冲区。该write(char[])方法返回实际写入Writer. 这是将字符数组写入 Java 的示例Writer:

char[] chars = new char[]{'A','B','C','D','E'}; 
bufferedWriter.write(chars);

2.3 write(String ) 写字符串

BufferedWriter writer=new BufferedWriter(new FileWriter("C:\\IO_Test\\data.txt",true));
         String str="hello world;";
         writer.write(str);
         writer.flush();
         writer.close();

2.4 写入性能

将字符数组写入 Java BufferedWriter 比一次写入一个字符要快。由于在BufferedWriter将字符写入底层之前收集内部写入缓冲区的字符Writer,因此加速不像其他Writer类(不使用缓冲)那么明显。但是,仍然有一个小的加速。

2.5 flush()

JavaBufferedWriter的flush()方法将写入到BufferedWriter 底层数据目的地的所有数据刷新。通过调用,flush()您可以确保任何缓冲的数据都将被刷新(写入)到磁盘(或网络,或任何其他目的地BufferedWriter)。以下是BufferedWriter通过调用Javaflush()方法刷新写入 Java的数据的示例:

bufferedWriter.flush();
  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猿小许

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值