服务器有这样一个需求,读取一个文件,然后通过socket传输给客户端,代码如下
这上面的代码看起来就是把文件读取到byte数组,然后在通过byte数组写给客户端。但其实经过了4次数据拷贝,三次内核系统切换。
因为java是没办法直接读取文件的,需要通过先将文件读取到内核缓冲区,然后在读取到用户缓冲区,也就是byte数组,同样java没办法直接写数据,需要先将数据转换存入到socket缓冲区,然后再将数据拷贝到网卡进行数据的发送。所以经过了4次数据拷贝,三次内核系统切换。
NIO进行改进1:
我们可以将上面的过程改为 从FileChannel读,写入ByteBuffer,然后从ByteBuffer读,向SocketChannel写。
但普通的ByteBuffer还不行,需要使用ByteBuffer.allocateDirect(16) , 该ByteBuffer使用的是操作系统的内存,该内存操作系统可以直接操作,java也可以直接操作,相当于文件数据从磁盘拷贝到了这块内存,java有可以直接操作这块内存,就只是这一步省略了一次数据的拷贝