问题 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构成的每个读取请求都会导致相应的读取请求>由基础字符或字节流构成。


11017
2018-03-06 06:07


起源



答案:


  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


3
2018-03-06 06:26



假设我有一个文本文件test.txt,其中包含三行> How> are> you这意味着Bufferedreader首先读取第一行,即How并将其放入缓冲区,然后读取并将其放入缓冲区然后将其放入buffer.Am我对吗?那么什么时候缓冲区会变空? - TruePS
它将读取n个字节或字符数据并存储到char数组中,而不是一次又一次地从i / o读取。记住每次读取操作都会更昂贵并且会对性能产生影响。让我们一个20000字节的文件,使用缓冲策略,你将首先读取,说512字节并存储一个数组,而不是每次读取所有这20000个字符的单个字节。 - UVM
因此它将读取整个3行你是如何将它存储到char数组中而char数组存入内存中的缓冲区。所以bufferedreader将读取缓冲区中的所有数据并显示它,并在读取所有数据后清空缓冲区。我现在好吗? - TruePS
读取char数组是BUFFERING。您可以在上面提到的链接中看到。 - UVM
1.它将创建一个具有默认大小的char数组,并将多个字符读入该数组,而不是行。然后它会从这个字符数组中形成一行字符串,并在调用readLine()时返回给你。如何存储到char数组中,请通过上面链接中的readLine()方法。在那里你可以看到如何使用这个char数组。希望现在你清楚这一点。 - UVM


答案:


  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


3
2018-03-06 06:26



假设我有一个文本文件test.txt,其中包含三行> How> are> you这意味着Bufferedreader首先读取第一行,即How并将其放入缓冲区,然后读取并将其放入缓冲区然后将其放入buffer.Am我对吗?那么什么时候缓冲区会变空? - TruePS
它将读取n个字节或字符数据并存储到char数组中,而不是一次又一次地从i / o读取。记住每次读取操作都会更昂贵并且会对性能产生影响。让我们一个20000字节的文件,使用缓冲策略,你将首先读取,说512字节并存储一个数组,而不是每次读取所有这20000个字符的单个字节。 - UVM
因此它将读取整个3行你是如何将它存储到char数组中而char数组存入内存中的缓冲区。所以bufferedreader将读取缓冲区中的所有数据并显示它,并在读取所有数据后清空缓冲区。我现在好吗? - TruePS
读取char数组是BUFFERING。您可以在上面提到的链接中看到。 - UVM
1.它将创建一个具有默认大小的char数组,并将多个字符读入该数组,而不是行。然后它会从这个字符数组中形成一行字符串,并在调用readLine()时返回给你。如何存储到char数组中,请通过上面链接中的readLine()方法。在那里你可以看到如何使用这个char数组。希望现在你清楚这一点。 - UVM


这里有两个问题。

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

我绕道而行,因为这就是全部 Readers不太适合图像。

Reader 有两个 read 方法:

 int read(); // returns one character, cast to an int
 int read(char[] block); // reads into block, returns how many chars it read

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

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

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

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

因此,如果您想读取整数,请使用 InputStream 不 ReaderInputStream 具有 int read(byte[] buf, int offset, int length)  - 字节比字符更可靠地来自int而不是字符。


7
2018-03-06 11:39



感谢您为我写了这么长的文章。我真的很感激,但是回答他们的其他用户知道BufferedReader是如何工作的,所以我也希望增强我对它如何工作的了解。当然,你的文章真的增加了我对如何知识的了解一个 围绕FileReader的BufferedReader将起作用 并且关于 缓冲 。 - TruePS
只是想说,很好的答案。 - Matthias


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

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

所以,回答你的问题:

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

4
2018-03-06 06:11



你能回答这个问题吗[stackoverflow.com/questions/22199220/... ] .Plz帮助,如果可以的话 - TruePS
我理解第一点和第三点但没有得到第二点缓冲读取器每次读取一行时都会创建一个新缓冲区并且你是说缓冲读取器从缓冲区读取数据以便节省我们的时间吗? - TruePS
@TruePS - 不,它适用于单个缓冲区。它提供来自该缓冲区的读取请求,当缓冲区变空时,它从底层流/读取器/任何填充缓冲区读取一个块。是的,这大大提高了性能。 - radai
好吧,我现在得到它只是我最后一件事让我说我有一个文本文件test.txt包含三行<code>如何<code> <code> <code> <code>你?<code>这意味着Bufferedreader首先先读取line ie如何将它放在缓冲区中,然后读取它并将其放入缓冲区然后将它放在缓冲区中。我是对的吗?那么何时缓冲区变空? - TruePS