而接闷厅收端接收到的都是bytebuf,然后我们接收端可以将其滚罩猜写到filechannel中。这样在接收端就可以写成文件了,从这样看我们的内存也不会因为传输的文件大而爆掉。因为我们底层是依靠transferTo的transferTo去循环发送文件数据
Netty 传输文件的时候没有使用 ByteBuf 进行向 Channel 中写入数据,而使用的 FileRegion。下面通过示例了解下 FileRegion 的用法,然后深入源码分析 为什么不使用 ByteBuf 而使用 FileRegion。
从示例中可以看出 ChannelPipeline 中添加了自定义的 FileServerHandler()。
下面看下 FileServerHandler 的源码,其它几个 Handler 的都是 Netty 中自带的,以后会分析这些 Handler 的具体实现原理。
从 FileServerHandler 中可以看轿含出,传输文件使用了 DefaultFileRegion 进行写入到 NioSocketChannel 里。
我们知道向 NioSocketChannel 里写数据,都是使闭含笑用的 ByteBuf 进行写入。这里为啥使用 DefaultFileRegion 呢?
DefaultFileRegion 中有一个很重要的方法 transferTo() 方法
这里可以看出 文件 通过 FileChannel.transferTo 方法直接发送到 WritableByteChannel 中。
通过 Nio 的 FileChannel 可以使用 map 文件映射的方式,直接发送到 SocketChannel中,这样可以减少两次 IO 的复制。
第一次 IO:读取文件的时间从系统内存中拷贝到 jvm 内存中。
第二次 IO:从 jvm 内存中写入 Socket 时,再 Copy 到系统内存中。
这就是所谓的零拷贝技术。
从 ChannelOutboundBuffer 中获取 FileRegion 类型的节点。
然后调用 NioSocketChannel.doWriteFileRegion() 方法进行写入。
这里调用 FileRegion.transferTo() 方法,使用 基于文老咐件内存映射技术进行文件发送。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)