BufferedInputStream和ByteArrayInputStream的区别

3
以下是三种将整个文件读入内存以进行处理的方法:
方法A:
fis = new FileInputStream(file);
bis = new BufferedInputStream(fis);
dis = new DataInputStream(bis);

方案B:

ByteArrayInputStream bi =
    new ByteArrayInputStream(
        org.apache.commons.io.FileUtils.readFileToByteArray(file))

方案C:

File file = new File(yourFileName);
RandomAccessFile ra = new RandomAccessFile(yourFileName, "rw"):
byte[] b = new byte[(int)file.length()];
try {
    ra.read(b);
} catch (Exception e) {
    e.printStackTrace();
}

我为什么会更喜欢某种方法而不喜欢另一种方法?
有没有特定的用例需要选择一种方法而不是另一种方法?
为什么不使用固定长度的 byte[] 代替?


4
你的三个示例做了三件不同的事情。 Case A 没有读取任何内容。 Case B 读取到一个字节数组,然后在该字节数组上打开一个流。 Case C 仅将内容读取到一个字节数组中。你真正想要实现什么? - JB Nizet
2
我认为他在询问应该使用什么来读取文件:a)常规java流 b)字节数组流还是c)RandomAccessFile。 - rocketboy
1
第四种方法,也可能是最有效的方法,是 Files.readAllBytes(Paths.get(yourFileName))。 - VGR
这只是关于效率吗?还是有更具体的情况导致了如此多可能性的出现?例如,既然我们已经有了缓冲区支持的解决方案BufferedInputStream,为什么还需要ByteArrayInputStream? - IUnknown
问题的标题有误导性。 - Taher
为什么你想一次性将文件的所有字节读入内存? - user207421
1个回答

4
除非你需要某些特殊的功能 (如随机访问),否则将InputStream包装成BufferedInputStream是从提供流功能的任何数据源中顺序读取的通用选择。这将提供合理的性能(通过缓冲),代码是通用的,因为它可以处理任何流,而且非常重要的是,可处理的流的大小不受此习语的可用堆内存的限制。因此,除非你有非常充分的理由编写针对特殊情况API的代码,否则请使用标准的InputStream并根据需要进行包装。
编辑:响应@IUnknown在评论中提出的问题:
1.在随机访问的情况下的方法是什么——我认为即使在这种情况下,BufferedInputStream也是首选的解决方案?
没有通用的随机访问接口。你想错了。你至少可以礼貌地研究基础知识:http://docs.oracle.com/javase/tutorial/essential/io/ 2.可处理流的大小不受可用堆内存的限制——缓冲区必须有一个限制。您是否在说当读取时内部数组会自动重新调整大小?
同样,在基础知识中有��盖(见上文)。对于ByteArrayInputStream,您需要一个byte[]来保存整个流。这不受内存的限制吗?(更糟糕的是,它还被最大数组大小硬限制)。
3.Buffered流和ByteArray流之间的缓冲区行为有什么区别——我认为它们都由类似的缓冲区行为支持?
我不知道该说什么。你想错了。放下他们都扩展InputStream和在技术上使用一个字节数组内部(实际上两者都可以实现而无需使用任何数组,只是这样做最自然的方式)。他们没有任何共同之处。BufferedStream保存另一个流的小动态部分。ByteArrayInputStream在2中讨论过。
建议:这里的人们将很乐意为您建议哪种工具适用于哪种工作。但不要期望被喂一口。展示一些努力,stackoverflow不是辅导网站。停止“思考”并开始“学习”——教程已经存在并从语言的黎明时期开始。

  1. 在随机访问的情况下,应采用什么方法 - 我以为即使在这种情况下,BufferedInputStream也是首选解决方案?
  2. 可处理流的大小不受可用堆内存的限制 - 缓冲区必须有一个限制。您是说在读取时,如果缓冲区已满,内部数组会自动重新调整大小吗?
  3. Buffered流和ByteArray流之间的缓冲区行为有什么区别吗? - 我认为它们都具有类似的缓冲区行为。
- IUnknown
@IUnknown 1. 随机访问缓冲是没有意义的,因为你刚刚从上次读取的缓冲区可能不是你接下来要读取的内容。2. BufferedInputStream 的内部字节数组长度是固定的。3. 区别在于 BufferedInputStream 不会一次性将所有内容读入内存,这是很好的。 - user207421

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接