Can BufferedReader可以读取字节吗?

对不起,如果这个问题很复杂,但我没有得到我想要的答案。

Java文档说这个

通常,由Reader构成的每个读取请求都会导致相应的读取请求由基础字符或字节流构成。 因此,建议将BufferedReader包装在任何read()操作可能代价高昂的Reader上,例如FileReaders>和InputStreamReaders。 例如,

BufferedReader in = new BufferedReader(new FileReader("foo.in")); 

将缓冲指定文件的输入。 如果没有缓冲,read()或readLine()的每次调用都可能导致从文件中读取字节,转换为字符,然后返回,这可能是非常低效的。

  1. 我的第一个问题是如果bufferedReader可以读取字节,那么为什么我们不能使用bufferedreader处理以字节为单位的图像。

  2. 我的第二个问题是 Bufferedreader是否在BUFFER中存储了字符,这一行的含义是什么

将缓冲指定文件的输入。

  1. 我的第三个问题是这条线的含义什么

通常,由Reader构成的每个读取请求都会导致相应的读取请求>由基础字符或字节流构成。

  1. 默认行为是它将转换为字符,但是当您有图像时,您不能拥有字符数据,而是需要像素字节数据。 所以你不能使用它。

  2. 它是buffereing,意思是它在char数组中读取一定数量的数据。 您可以在代码中看到此行为:

  public BufferedReader(Reader in) { this(in, defaultCharBufferSize); } 

defaultCharBufferSize如下所述:

private static int defaultCharBufferSize = 8192;

 3 Every time you do read operation, it will be reading only one character. 

所以简而言之,buffred意味着,它将首先读取少量字符数据,这些数据将保留在char数组中并且将被处理,并且它将再次读取相同的数据块,直到它到达流的末尾

您可以参考以下内容以了解更多信息

的BufferedReader

这里有两个问题。

1.缓冲

想象一下,你距离最近的水源一英里,你每小时喝一杯水。 好吧,你不会因为每一杯都一直走到水边。 每天去一次,带着满满水的水桶回家,24次。

桶是缓冲区

想象一下,你的村庄是河边的供水。 但有时河水干了一个月; 其他时候,河流带来了如此多的水,村庄洪水泛滥。 所以你建造了一座大坝,在大坝后面有一个水库。 水库在雨季填满,并在旱季逐渐清空。 这个村庄全年都有稳定的水流。

水库是一个缓冲区

计算中的数据流与这两种情况类似。 例如,您可以在单个OS系统调用中从文件系统获取几千字节的数据,但如果您希望一次处理一个字符,则需要类似于库的内容。

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是读者的例子非常重要。 您可能还没有涵盖编程教育中的多态性,所以当您这样做时,请记住这一点。 这意味着如果您有使用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 

第二种forms不适合图像,因为它肯定会读取字符,而不是整数。

第一个表单看起来好像可以 – 毕竟,它读取整数。 事实上,如果你只是使用FileReader,它可能会工作。

但是,请考虑一下围绕FileReader的BufferedReader如何工作。 第一次调用BufferedReader.read()时,它将调用FileReader.read(缓冲区)来填充其缓冲区。 然后它会将缓冲区的第一个char回int,然后返回。

特别是当你将多字节字符集带入图片时,这可能会导致问题。

因此,如果要读取整数,请使用InputStream而不是ReaderInputStreamint read(byte[] buf, int offset, int length) – 字节比字符串来回更加可靠地来回转换。

java中的读者(和写作者)是用于处理文本(字符)流的专用类 – 在任何其他类型的流中,行的概念都是无意义的。

对于一般IO等效,请看一下BufferedInputStream

所以,回答你的问题:

  1. 当读者最终读取字节时,它会将它们转换为字符。 它不打算读取任何其他内容(如图像) – 使用InputStream类系列
  2. 缓冲读取器将从底层流(可能是文件,套接字或其他任何内容)中读取大块数据到内存中的缓冲区,然后从缓冲区中清除缓冲区的读取请求。 这种读取大块而不是较小的夹头的行为每次都会提高性能。
  3. 这意味着如果你将读卡器包装在缓冲读卡器中,那么每次你想要读取一个字符时,它都会访问disk.network来获得你想要的单个字符。 在如此小的块中进行I / O通常对性能很糟糕。