Can BufferedReader可以读取字节吗?

时间:2014-03-06 06:07:32

标签: java file-handling

很抱歉,如果这个问题很复杂,但我找不到我想要的答案。

Java docs说这个

  

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

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

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

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

  2. 我的第二个问题是 Bufferedreader是否在BUFFER中存储字符以及此行的含义

  3.   

    将缓冲指定文件的输入。

    1. 我的第三个问题是这一行的含义是什么
    2.   

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

3 个答案:

答案 0 :(得分:7)

这里有两个问题。

<强> 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

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

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

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

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

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

答案 1 :(得分:4)

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

对于通用IO等效项,请查看BufferedInputStream

所以,回答你的问题:

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

答案 2 :(得分:3)

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

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

  3.  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