在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();