【问题标题】:java : Does using buffered input stream make the conversion of input streams to byte[] more efficient?java : 使用缓冲输入流是否使输入流到字节 [] 的转换更有效?
【发布时间】:2018-04-26 09:12:43
【问题描述】:

我想将输入流转换为字节[],我正在使用IOUtils.toByteArray(inputStream)。通过为 inputStream 使用像 BufferedInputStream 这样的包装器会提高效率吗?是否节省内存?

【问题讨论】:

    标签: java bufferedinputstream


    【解决方案1】:

    通过像 BufferedInputStream 这样的包装器会提高效率吗? 输入流?

    没有任何意义。 IOUtils.toByteArray 将数据读入一个 4096 字节的缓冲区。 BufferedInputStream 默认使用 8192 字节的缓冲区。 使用 BufferedInputStream 会减少 IO 读取,但您需要一个非常快速的数据源才能发现任何差异。

    如果您一次读取一个字节(或几个字节)的 InputStream,那么使用 BufferedInputStream 确实可以提高性能,因为它将操作系统调用的数量减少了 8000 倍。而且操作系统调用需要很多时间, 比较。

    它会节省内存吗?

    没有。 IOUtils.toByteArray 将创建一个new byte[4096],无论是传入缓冲的还是非缓冲的 InputStream。 BufferdedInputStream 需要更多的内存来创建。但没什么大不了的。

    【讨论】:

    • 感谢您的回复,我明白您的回答。在我的场景中,我正在尝试将数百个文件的字节 [] 从文件系统保存到数据库。在这数百个文件的转换过程中,有时我会耗尽堆空间。因此,如果我开始使用缓冲的输入流并不会产生任何显着差异?
    • @AravindS 如果每个文件都代表一个实体列表,您正在插入到您的数据库中,这是处理它的最佳方式,而不是调用IOUtils.toByteArray 一次读取整个文件,分批读取,例如获取文件中的前 1000 个实体,将它们写入数据库,提交事务,然后读取下一个 1000,您将始终只需要为一个实体分配内存,您可以控制其大小。
    • 这就是我在 for 循环中所做的。我反复面对这个问题。所以我一次读取一个文件,提交事务。只要我有任何文件,就重复这个循环。我这样做只是为了看看它是否有效,但我仍然面临内存不足的异常。
    • @AravindS 是的,这是您的问题,请仔细阅读我的评论,IOUtils.toByteArray 会立即完整读取您的文件,因此您会将整个文件内容保存在内存中,如果您改为调用 @ 987654329@ 并读取 1000 行,然后将它们提交到数据库,然后继续当前文件中的下 1000 行,那么您的内存中某一时刻将只有 1000 行文件,而不是整个文件。
    • 好的,是不是像读取前 1000 行,将其作为字节数组保存到数据库,读取接下来的 1000 行并将其保存到数据库直到到达文件末尾?跨度>
    【解决方案2】:

    就最终的内存消耗而言,这无济于事,因为无论如何您都需要将整个流移动到byte[],数组的大小将是相同的,因此内存消耗将是相同的。

    BufferedInputStream 的作用是包装另一个流,而不是直接写入它,它会将您的输入缓冲到内部缓冲区中,并且仅当它 closes/flushes 或内部缓冲区已满时才写入底层流。它可以使您的写入操作更快,因为您将分批执行它们而不是每次都直接写入,但是如果您从另一端读取它也无济于事。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-06-18
      • 1970-01-01
      • 1970-01-01
      • 2016-07-14
      • 2015-01-09
      • 2014-09-14
      • 2014-01-02
      • 2011-05-15
      相关资源
      最近更新 更多