繁体   English   中英

FileChannel和FileInputStream中read(ByteBuffer)和read(byte [])之间的区别

[英]difference between read(ByteBuffer) and read(byte[]) in FileChannel and FileInputStream

刚来NIO ,发现有一篇文章说“ 基于块的传输通常比基于流的传输更有效 ”。 这意味着read(ByteBuffer)是基于块的传输,而read(byte [])是基于流的传输。

我想知道两种方法之间的内部区别是什么。

ps:我也听到基于块的传输正在传输字节数组,而基于流的传输正在逐字节传输字节。 我认为这是错误的,因为java.io.FileInputStream.read(byte [])也会传输字节数组。

使字节缓冲区更有效的一件事是使用直接内存。 这样可以避免将直接存储器中的副本复制到byte []中。 如果仅将数据从一个通道复制到另一个通道,则速度最高可提高30%。 如果逐字节读取,使用ByteBuffer可能会稍慢一些,因为访问每个字节的开销更大。 如果使用它读取二进制(例如intdouble ,则可以更快,因为它可以一次访问所有值。

我认为你是在谈论buffer-based VS stream-based I / O操作。 Java NIO是面向缓冲区的,即首先将数据读入缓冲区然后进行处理。 这提供了一种灵活性。 另外,在处理缓冲区之前,您需要确保缓冲区具有所需的所有数据。 另一方面,使用stream-based I / O,您将从流中读取一个或多个字节,这些字节不会缓存在任何地方。 这是一个阻塞I / O,而buffer-based I / O(Java NIO)是一个非阻塞IO。

尽管我不会使用“基于流的”来表征read(byte[]) ,但在某些情况下, ByteBuffer效率要高于byte[]

请参见关于何时应将直接缓冲区与Java NIO一起用于网络I / O的简单规则? ByteBuffer.allocate()与ByteBuffer.allocateDirect()

支持ByteBuffer的内存可以使JVM更容易(如果是“直接”)传递给OS并执行IO技巧(例如,直接传递内存以进行读写调用),并且可能不会“打开” JVM的堆。 支持byte[]的内存在JVM堆上,并且IO通常不会直接进入数组使用的内存中(相反,它通常会通过反弹缓冲区---因为GC可能会在内存中“移动”数组对象IO未决或阵列内存可能不连续)。

但是,如果您必须使用Java操作数据,则ByteBuffer可能不会有太大的不同,因为最终您将不得不将数据复制到Java堆中以对其进行操作。 如果您要在不进行任何操作的情况下进行数据复制进出,则直接使用ByteBuffer可能是一个成功。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM