码迷,mamicode.com
首页 > 编程语言 > 详细

Java NIO2

时间:2016-04-26 15:51:09      阅读:212      评论:0      收藏:0      [点我收藏+]

标签:

Java NIO Scatter((使) 散开,(使)分散,驱散)/ Gather(收集; 采集; 聚集,搜集; 收紧,收缩)

Java NIO comes with built-in scatter/gather support. Scatter/gather are concepts used in reading from, and writing to channels.
A scattering read from a channel is a read operation that reads data into more than one buffer(把数据读入不止一个缓存Buffer). Thus, the channel "scatters" the data from the channel into multiple buffers.
A gathering write to a channel is a write operation that writes data from more than one buffer into a single channel(把多个缓存中的数据写入通道Channel). Thus, the channel "gathers" the data from multiple buffers into one channel.
Scatter / gather can be really useful in situations where you need to work with various parts of the transmitted data separately. For instance, if a message consists of a header and a body, you might keep the header and body in separate buffers. Doing so may make it easier for you to work with header and body separately.

Scattering Reads
A "scattering read" reads data from a single channel into multiple buffers.
Here is an illustration of the Scatter principle:

技术分享

 Here is a code example that shows how to perform a scattering read:

ByteBuffer header = ByteBuffer.allocate(128);
ByteBuffer body   = ByteBuffer.allocate(1024);
ByteBuffer[] bufferArray = { header, body };
//read(ByteBuffer[] dsts)
channel.read(bufferArray);

Notice how the buffers are first inserted into an array, then the array passed as parameter to the channel.read() method. The read() method then writes data from the channel in the sequence the buffers occur in the array. Once a buffer is full, the channel moves on to fill the next buffer.
The fact that scattering reads fill up one buffer before moving on to the next, means that it is not suited for dynamically sized message parts. In other words, if you have a header and a body, and the header is fixed size (e.g. 128 bytes), then a scattering read works fine.

Gathering Writes
A "gathering write" writes data from multiple buffers into a single channel.

Here is an illustration of that principle:

技术分享

Here is a code example that shows how to perform a gathering write:

ByteBuffer header = ByteBuffer.allocate(128);
ByteBuffer body   = ByteBuffer.allocate(1024);
//write data into buffers
ByteBuffer[] bufferArray = { header, body };
channel.write(bufferArray);

The array of buffers are passed into the write() method, which writes the content of the buffers in the sequence they are encountered in the array. Only the data between position and limit of the buffers is written. Thus, if a buffer has a capacity of 128 bytes, but only contains 58 bytes, only 58 bytes are written from that buffer to the channel. Thus, a gathering write works fine with dynamically sized message parts, in contrast to scattering reads.

Java NIO Channel to Channel Transfers

In Java NIO you can transfer data directly from one channel to another, if one of the channels is a FileChannel. The FileChannel class has a transferTo() and a transferFrom() method which does this for you.

transferFrom()
The FileChannel.transferFrom() method transfers data from a source channel into the FileChannel.

/**
     * Transfers bytes into this channel‘s file from the given readable byte
     * channel.
*/
 public abstract long transferFrom(ReadableByteChannel src,
                                      long position, long count)
        throws IOException;

Here is a simple example:

RandomAccessFile fromFile = new RandomAccessFile("fromFile.txt", "rw");
FileChannel      fromChannel = fromFile.getChannel();

RandomAccessFile toFile = new RandomAccessFile("toFile.txt", "rw");
FileChannel      toChannel = toFile.getChannel();

long position = 0;
long count    = fromChannel.size();

toChannel.transferFrom(fromChannel, position, count);

The parameters position and count, tell where in the destination file to start writing (position), and how many bytes to transfer maximally (count). If the source channel has fewer than count bytes, less is transfered.
Additionally, some SocketChannel implementations may transfer only the data the SocketChannel has ready in its internal buffer here and now - even if the SocketChannel may later have more data available. Thus, it may not transfer the entire data requested (count) from the SocketChannel into FileChannel.

transferTo()
The transferTo() method transfer from a FileChannel into some other channel.

/**
     * Transfers bytes from this channel‘s file to the given writable byte
     * channel.
*/
public abstract long transferTo(long position, long count,
                                    WritableByteChannel target)
        throws IOException;

Here is a simple example:

RandomAccessFile fromFile = new RandomAccessFile("fromFile.txt", "rw");
FileChannel      fromChannel = fromFile.getChannel();

RandomAccessFile toFile = new RandomAccessFile("toFile.txt", "rw");
FileChannel      toChannel = toFile.getChannel();

long position = 0;
long count    = fromChannel.size();

fromChannel.transferTo(position, count, toChannel);

Notice how similar the example is to the previous. The only real difference is the which FileChannel object the method is called on. The rest is the same.
The issue with SocketChannel is also present with the transferTo() method. The SocketChannel implementation may only transfer bytes from the FileChannel until the send buffer is full, and then stop.

 

Java NIO2

标签:

原文地址:http://www.cnblogs.com/winner-0715/p/5435227.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!