这里有两个问题。
1. 缓冲
想象一下,你住在离你最近的水源一英里的地方,每小时喝一杯水。好吧,你不会为每杯都走到水边。每天去一次,回家时要带上一个装满足够水的水,可以装满杯子24次。
存储桶是缓冲区。
想象一下,你的村庄由一条河供水。但有时河水干涸一个月;其他时候,河流带来了如此多的水,以至于村庄被洪水淹没。所以你建了一座大坝,大坝后面有一个水库。水库在雨季填满,在旱季逐渐排空。该村全年水源不断。
水库是一个缓冲区。
计算中的数据流类似于这两种方案。例如,您可以在单个操作系统系统调用中从文件系统中获取几千字节的数据,但是如果要一次处理一个字符,则需要类似于存储库的东西。
BufferedReader包含另一个Reader(例如FileReader),它是河流 - 以及一个字节数组,这是水库。每次你从中阅读时,它都会做这样的事情:
if there are not enough bytes in the "reservoir" to fulfil this request
top up the "reservoir" by reading from the underlying Reader
endif
return some bytes from the "reservoir".
但是,当您使用BufferedReader时,您不需要知道它是如何工作的,只需要知道它是如何工作的。
2. 图像适用性
重要的是要了解 BufferedReader 和 FileReader 是 Reader 的示例。你可能还没有在你的编程教育中涵盖多态性,所以当你这样做的时候,记住这一点。这意味着,如果你有代码使用 - 但只有符合它的方面 - 那么你可以替换a,它将工作相同。FileReader
Reader
BufferedReader
将变量声明为最通用的类是一个好习惯:
Reader reader = new FileReader(file);
...因为这将是您需要添加缓冲的唯一更改:
Reader reader = new BufferedReader(new FileReader(file));
我绕道而行,因为这些都是不太适合图像的。Reader
Reader
有两种方法:read
int read(); // returns one character, cast to an int
int read(char[] block); // reads into block, returns how many chars it read
第二种形式不适合图像,因为它肯定读的是字符,而不是整数。
第一种形式看起来好像没问题 - 毕竟,它读的是ints。事实上,如果您只使用FileReader,它可能会很好地工作。
但是,请考虑一下包裹在FileReader周围的缓冲阅读器将如何工作。第一次调用 BufferedReader.read() 时,它将调用 FileReader.read(buffer) 来填充其缓冲区。然后,它将缓冲区的第一个转换回 int,并返回该。char
特别是当您将多字节字符集带入图片时,这可能会导致问题。
因此,如果要读取整数,请不要使用 。 有 - 字节比字符更可靠地从int来回转换。InputStream
Reader
InputStream
int read(byte[] buf, int offset, int length)