【问题标题】:What can be replaced by fileInputStream.available()?fileInputStream.available() 可以代替什么?
【发布时间】:2019-03-18 09:01:57
【问题描述】:

在学习Java IO的时候发现fileInputStream有一个availabl()方法,可以等于读取本地文件时的文件大小。那么如果可以直接知道文件的大小,那么在需要读取整个文件的情况下,有必要用BufferedInputStream来装饰一下吗? 像这样:

      FileInputStream fileInputStream=new FileInputStream("F:\\test.txt");
      byte[] data=new byte[fileInputStream.available()];
      if (fileInputStream.read(data)!=-1) {
           System.out.println(new String(data));
      }

   BufferedReader bufferedReader=new BufferedReader(new 
   FileReader("F:\\test.txt"));
   StringBuilder stringBuilder=new StringBuilder();
   for (String line;(line=bufferedReader.readLine())!=null;){
       stringBuilder.append(line);
    }
   System.out.println(stringBuilder.toString());

     BufferedInputStream bufferedInputStream=new BufferedInputStream(new FileInputStream("F:\\test.txt"));
     byte[] data=new byte[bufferedInputStream.available()];
     if (bufferedInputStream.read(data)!=-1) {
           System.out.println(new String(data));
      }

这些方法的优缺点是什么?哪一个更好? 谢谢。

【问题讨论】:

  • 在内存使用方面缓冲会有所帮助,因为您不必先将所有内容读入内存。话虽如此,我会采用您最熟悉的方法 - 如果所有 3 种方法都有效。但是,IMO 在所有 3 个 sn-ps 中都有一个主要流程:您没有提供有关文件编码的任何信息,因此将字节转换为字符的部分将使用系统的默认编码。这可能偶然是正确的,但这就是问题所在:你把它留给了机会。
  • 如果它曾经'在读取本地文件时等于文件大小',这是一个意外,当你从文件中读取一个字节时它就会停止。它所做的只是告诉您当前可以从流无阻塞地读取多少字节,这完全是一个不同的鱼缸。 Javadoc against 中有特定警告,正如您在上面那样使用它。如果您需要的话,有现有的方法可以获取任何文件的大小。但你很少这样做。您不应该尝试将整个文件加载到内存中。
  • 第一个不正确,因为使用了available(),如上所示。而且您正在使用 Stream 而不是 Reader 来读取字符。第二个是不正确的,因为它从您阅读的内容中删除了所有行尾。第三个是不正确的,因为使用了available()。谷歌“Java IO 教程”。它有正确的例子。
  • 第三个也不正确,因为您忽略了read() 返回的读取计数。假设你告诉我们你真正想要做什么?
  • 简而言之,缓冲只有在你有大量的短读/写时才有用。它只会增加大量读取/写入的开销。这不是魔法;)

标签: java java-io


【解决方案1】:

您对available() 的含义有误。它返回您可以在不阻塞的情况下读取的可能的字节数。来自文档:

请注意,虽然 InputStream 的某些实现会返回流中的总字节数,但很多不会。使用该方法的返回值来分配一个用于保存该流中所有数据的缓冲区是不正确的。

所以,如果你想将流转换为字节数组,你应该使用相应的库,例如IOUtils:

byte[] out = IOUtils.toByteArray(stream);

【讨论】:

  • 感谢@user207421 版本。我编辑了一下:available 返回可能的(不是最大)字节数,因为根据文档可用返回an estimate of the number of bytes that can be read (or skiiped over)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多