【发布时间】:2018-04-26 09:12:43
【问题描述】:
我想将输入流转换为字节[],我正在使用IOUtils.toByteArray(inputStream)。通过为 inputStream 使用像 BufferedInputStream 这样的包装器会提高效率吗?是否节省内存?
【问题讨论】:
我想将输入流转换为字节[],我正在使用IOUtils.toByteArray(inputStream)。通过为 inputStream 使用像 BufferedInputStream 这样的包装器会提高效率吗?是否节省内存?
【问题讨论】:
通过像 BufferedInputStream 这样的包装器会提高效率吗? 输入流?
没有任何意义。 IOUtils.toByteArray 将数据读入一个 4096 字节的缓冲区。 BufferedInputStream 默认使用 8192 字节的缓冲区。
使用 BufferedInputStream 会减少 IO 读取,但您需要一个非常快速的数据源才能发现任何差异。
如果您一次读取一个字节(或几个字节)的 InputStream,那么使用 BufferedInputStream 确实可以提高性能,因为它将操作系统调用的数量减少了 8000 倍。而且操作系统调用需要很多时间, 比较。
它会节省内存吗?
没有。 IOUtils.toByteArray 将创建一个new byte[4096],无论是传入缓冲的还是非缓冲的 InputStream。 BufferdedInputStream 需要更多的内存来创建。但没什么大不了的。
【讨论】:
IOUtils.toByteArray 一次读取整个文件,分批读取,例如获取文件中的前 1000 个实体,将它们写入数据库,提交事务,然后读取下一个 1000,您将始终只需要为一个实体分配内存,您可以控制其大小。
IOUtils.toByteArray 会立即完整读取您的文件,因此您会将整个文件内容保存在内存中,如果您改为调用 @ 987654329@ 并读取 1000 行,然后将它们提交到数据库,然后继续当前文件中的下 1000 行,那么您的内存中某一时刻将只有 1000 行文件,而不是整个文件。
就最终的内存消耗而言,这无济于事,因为无论如何您都需要将整个流移动到byte[],数组的大小将是相同的,因此内存消耗将是相同的。
BufferedInputStream 的作用是包装另一个流,而不是直接写入它,它会将您的输入缓冲到内部缓冲区中,并且仅当它 closes/flushes 或内部缓冲区已满时才写入底层流。它可以使您的写入操作更快,因为您将分批执行它们而不是每次都直接写入,但是如果您从另一端读取它也无济于事。
【讨论】: