【问题标题】:BufferInputStream vs ByteArrayInputStreamBufferedInputStream 与 ByteArrayInputStream
【发布时间】:2013-08-19 21:48:05
【问题描述】:

以下是在处理之前将整个文件读入内存的三种方法:

方法 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[]

【问题讨论】:

  • 您的 3 个案例做了 3 件不同的事情。案例 A 没有读取任何内容。案例 B 读入一个字节数组,然后在字节数组上打开一个流。案例 C 读入一个字节数组。你真正想达到什么目标?
  • 我想他在问他应该使用哪个来读取文件:a) 常规 java 流 b) Bytearray 流或 c) RandomAccessFile
  • 第四种方法,可能也是最有效的方法是Files.readAllBytes(Paths.get(yourFileName))。
  • 这仅仅是关于效率 - 还是有更具体的情况导致了这么多可能的替代方案?例如,当我们在 BufferedInputStream 中有缓冲区支持的解决方案时,为什么会出现 ByteArrayInputStream?
  • 问题的标题具有误导性。

标签: java file-io inputstream


【解决方案1】:

除非您需要任何特殊的功能(例如随机访问),否则包装到 BufferedInputStream 中的 InputStream 是从提供流式传输功能的任何类型的数据源顺序读取的通用选择。

这将提供合理的性能(通过缓冲),代码是通用的,因为它可以处理任何流,而且非常重要 - 可处理流的大小不受此习惯用法可用堆内存的限制。

因此,除非您有非常令人信服的理由针对特殊情况 API 进行编码,否则请使用标准 InputStream 并根据需要对其进行包装。


编辑:回应@IUnknown评论中提出的问题:

  1. 在随机访问的情况下,我认为 BufferedInputStream 是首选解决方案,即使在这种情况下也是如此?

没有用于随机访问的通用接口。你想错了。你至少可以有礼貌地学习基础知识:http://docs.oracle.com/javase/tutorial/essential/io/

  1. 可处理流的大小不受可用堆内存的限制 - 缓冲区必须有限制。您是说如果内部数组在读取时被填满,它会自动重新调整大小?

同样,这已包含在基础知识中(见上文)。使用 ByteArrayInputStream 您需要一个 byte[] 来保存整个流。这怎么受内存限制? (更糟糕的是,它还受到最大数组大小的限制)。

  1. Buffered 流和 ByteArray 流之间的缓冲区行为是否有任何差异 - 我认为它们由类似的缓冲区行为支持

我不知道该说什么。你想错了。撇开基本事实不谈,它们都扩展了 InputStream 并以某种方式在内部使用字节数组(从技术上讲,两者都可以在不使用任何数组的情况下实现,这只是最自然的方法)。他们没有共同点。 BufferedStream 保存 另一个 流的一小部分动态。 ByteArrayInputStream 已在 2 中介绍过。

建议:这里的人们很乐意为您提供关于使用哪种工具完成哪项工作的建议。但不要指望被勺子喂食。显示一些的努力,stackoverflow 不是一个辅导网站。停止“思考”并开始“学习” - 教程就在那里,并且自语言诞生之日起就一直存在。

【讨论】:

  • 1.在随机访问的情况下,我认为 BufferedInputStream 是首选解决方案,即使在这种情况下也是如此? 2. 可处理流的大小不受可用堆内存的限制——缓冲区必须有限制。你是说如果内部数组在读取时被填满,它会自动重新调整大小吗? 3.缓冲流和字节数组流之间的缓冲行为是否有任何区别-我认为它们是由类似的缓冲行为支持的
  • @IUnknown 1. 使用随机访问进行缓冲是没有意义的,因为您上次阅读时刚刚缓冲的内容可能不是您接下来要阅读的内容。 2、BufferedInputStream的内部字节数组是固定长度的。 3.不同的是BufferedInputStream不会一次把所有的东西都读入内存,这很好。
猜你喜欢
  • 1970-01-01
  • 2012-06-18
  • 1970-01-01
  • 2017-05-05
  • 2020-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多