【发布时间】: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()返回的读取计数。假设你告诉我们你真正想要做什么? -
简而言之,缓冲只有在你有大量的短读/写时才有用。它只会增加大量读取/写入的开销。这不是魔法;)