NIO学习笔记--Channel通道基础

本文介绍了Java NIO中的通道(Channel)概念,包括其与传统IO流的区别、双向读写特性及异步处理能力。文章详细阐述了FileChannel、DatagramChannel、SocketChannel等通道的应用场景,并提供了使用FileChannel进行数据读取的示例代码。此外,还介绍了scatter/gather操作、通道间的数据传输方法及其应用场景。

Java NIO Channel通道和IO中流的不同;

1.双向通道,既可以读取也可以写入;

2.通道可以异步读写

3.通道中的数据总是要先读到一个Buffer.或总是要从一个Buffer中写入

一.Channel的实现类

FileChannel: 从文件中读写数据;

DatagramChannel: 能通过UDP读写网络中的数据;

SocketChannel: 能从TCP读写网络中的数据;

ServerSocketChannel : 可以监听新建立的TCP连接,和Web服务器一样,每建立一个新的连接都会创建一个SocketChannel

基本的 Channel 示例

下面是一个使用FileChannel读取数据到Buffer中的示例:

RandomAccessFile aFile = new RandomAccessFile("data/nio-data.txt", "rw");
FileChannel inChannel = aFile.getChannel();
ByteBuffer buf = ByteBuffer.allocate(48);
int bytesRead = inChannel.read(buf);
while (bytesRead != -1) {
System.out.println("Read " + bytesRead);
buf.flip();
while(buf.hasRemaining()){
System.out.print((char) buf.get());
}
buf.clear();
bytesRead = inChannel.read(buf);
}
aFile.close();

注意 buf.flip() 的调用,首先读取数据到Buffer,然后反转Buffer,接着再从Buffer中读取数据。下一节会深入讲解Buffer的更多细节。

二.Scatter/Gather

scatter/Gather用于将传输的数据分开处理的的场合,

Java NIO开始支持scatter/gather,scatter/gather使用描述从Channel中读取或者写入到Channel的操作

分散(scatter) 从Channel中读取时将读取的数据写入多个buffer中,Chanel将从Channel中读取的数据scatter到多个Buffer;

聚集(gather)写入Channel是指在写操作时将多个buffer的数据写入同一个Channel,Channel将多个Buffer中的数据gather后发送到Channel;

Scattering Reads

Scattering Reads是指从一个channel读取到多个Buffer中.使用read(bufferArray)方法可以实现,read方法按照buffer在数组中的顺序从channel中读取的数据写入到buffer,当一个buffer写满后会接着向另一个buffer中写(写满之后才能变更,不适合动态大小的消息,使用时,注意buffer大小的确定).

Gathering Writes

指将多个buffer中的数据写入同一个channel,和Scattering Reads一样先将多个buffer整合到一个BufferArray中然后使用write(BufferArray)方法按数组顺序写入到channel中,注意只有在position和limit中的数据会被写入到channel中,因此和Scattering Reads比起来Gathering Writes可以很好的处理动态大小的消息(笔记:利用limit和position实现)

三.Channel to Channel Transfers 通道传输

在Java NIO中如果是一个FileChannel可以直接从一个channel传递数据到其他地方,FileChannel类通过transferTo()和transferFrom()方法来实现这个

transferFrom()

这个方法可以从一个source channel(源通道)传递数据到FileChannel中,使用方法:toChannel.transferFrom(fromChannel,position,count),其中position参数表示从目标文件的写入位置,count表示最大的传输字节,如果source channel的剩余空间小于最大传输字节,传输的字节要小于请求的字节数,此外,一些SocketChannel实现中,SocketChannel只能传输已经在内存缓冲区准备好的数据即使SocketChannel中有更多的数据存在,因此SocketChannel可能不会将所有数据(count个字节)全部传输到FileChannel中

demo

transferTo()

这个方法可以从一个FileChannel传递数据到其他channel中,和transferFrom()一样,SocketChannel的问题也一样,SocketChannel实现会从FileChannel中传递字节知道buffer被填满,然后停止









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值