Channels 是 IO Stream 上的包装器吗?
Posted
技术标签:
【中文标题】Channels 是 IO Stream 上的包装器吗?【英文标题】:Are Channels wrappers over IO Stream? 【发布时间】:2017-06-26 01:00:36 【问题描述】:我想知道区别以清除概念上的差异,因为我已经看到了SocketChannel
、FileChannel
等类。与 Socket
和文件 I/O 流相比
据我所知,I/O 流必须按顺序访问,即它们是可以读取和写入的字节序列。您还可以使用 Buffered Stream 来提高 I/O 效率。
那么,与 Streams 相比,“Channels”是一个全新的概念还是只是 Streams 的封装?
是的,如果我们说“Stream 是一个字节序列”,那么如果两者都不同,那么在这个意义上什么是 Channel?
【问题讨论】:
全新。因此nio
(或“新 io”)。 IO 流可能在某个时候在通道上实现,而不是相反。
没有。他们不可能。流没有非阻塞模式。它们不能异步关闭。流写入不返回计数。流中没有足够的特性来实现 NIO 的所有特性。
【参考方案1】:
两者都没有。通道不是流的包装器(除非您通过 Channels.newChannel(InputStream)
或 Channels.newChannel(OutputStream)
显式包装流),它们不是“全新的概念”。
根据特定的类型,通道仍然表示可以按顺序读取或写入的字节序列。您可以通过 Channels
类中的工厂方法在这些 API 之间进行转换这一事实表明存在关系。
但是 NIO API 解决了某些设计问题,这些问题无法通过重构旧的流类(以兼容的方式)来解决。例如。基本类型现在是接口,它允许某些通道同时实现多种类型,例如ReadableByteChannel
和WritableByteChannel
。此外,没有读取单个字节的方法,这是摆脱“您可以使用 BufferedStream 提高效率”神话的好方法。如果缓冲区大小不足是导致 I/O 性能瓶颈的原因,您首先通过提供更大的缓冲区来解决它,而不是将流或通道包装到另一个中,强制它在缓冲区之间复制所有数据。因此,没有BufferedChannel
。
除了顺序访问之外,FileChannel
等某些实现还提供了额外的方法,允许随机访问底层资源。这样,您可以使用统一的接口,而不是处理完全不同的 API,例如 RandomAccessFile
/ InputStream
/ OutputStream
关系。
此外,在引入 NIO 时,添加了许多以前缺少的 I/O 功能。其中一些可以毫无问题地在旧类上实现,但设计人员显然更倾向于为所有这些类使用新的 API,这些特性可以从一开始就在设计中考虑。
但一般来说,如前所述,与流相比,频道并不是一个全新的概念。
【讨论】:
以上是关于Channels 是 IO Stream 上的包装器吗?的主要内容,如果未能解决你的问题,请参考以下文章
java学习笔记:Java 流(Stream)文件(File)和IO
java.io.IOException:流已重置:多个设备上的 REFUSED_STREAM