关于IO,我有两个问题。
A。在一个教程和一些StackOverflow答案中,他们声称FileInputStream
没有被缓冲。是真的吗?
以下代码使用FileInputStream
将数据读入字节数组(1024个字节)
class Test {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("./fos.txt");
FileOutputStream fos = new FileOutputStream("./copy.txt");
byte[] buffer = new byte[1024]; // Is this a buffer ?
int len;
while ((len = fis.read(buffer))!= -1) {
fos.write(buffer);
}
fos.close();
fis.close();
}
}
在API中,只有一行:
公共int读取(字节b [])抛出IOException
- @param b:读取数据的缓冲区。
B。如果它们都被缓冲了,它们都将数据放入缓冲区中,并从缓冲区中获取数据,正是BufferedInputStream
比FileInputStream
快的地方在哪里?
谢谢
答案 0 :(得分:5)
在一个教程和一些StackOverflow答案中,他们声称FileInputStream没有被缓冲。是真的吗?
写入任何文件都由OS缓冲,但是在这种情况下,它不被Java缓冲。当您执行许多小写操作时,缓冲有助于实现1 KB的写操作。
以下代码使用FileInputStream将数据读入字节数组(1024个字节)
int len;
while ((len = fis.read(buffer))!= -1) {
fos.write(buffer);
}
此循环已中断,因为它假定您始终精确地读取1024个字节,并且文件长度始终是1024的倍数。
相反,您应该写出读取的长度。
for (int len; (len = fis.read(buffer))!= -1; )
fos.write(buffer, 0, len);
如果它们都被缓冲了,它们都将数据放入缓冲区中,并从缓冲区中获取数据,正是在这里使BufferedInputStream比FileInputStream快?
在这种情况下,BufferedInputStream默认情况下将使用8 KB缓冲区。这样最多可以将系统调用次数减少8倍,但是,在您的情况下,仅使用8 KB byte[]
并保存一些冗余副本会更加简单。
public static void main(String[] args) throws IOException {
try (FileInputStream fis = new FileInputStream("./fos.txt");
FileOutputStream fos = new FileOutputStream("./copy.txt")) {
byte[] buffer = new byte[8 << 10]; // 8 KB
for (int len; (len = fis.read(buffer)) != -1; )
fos.write(buffer, 0, len);
}
}
答案 1 :(得分:1)
的确,FileInputStream没有缓冲,但是在读取时确实提供了有限的缓冲,如能力。
最大的区别是BufferedInputStream支持mark()和reset(),而FileInputStream不支持。
mark(int readlimit)将允许您设置流中的位置以备后用。 reset()会将您在流中的位置设置为mark(int readLimit)中指定的位置
要支持mark()和reset(),BufferedInputStream必须维护一个内部缓冲区,而FileInputStream则不会。