本文参考至:http://ifeve.com/java-nio-scattergather/
首先看看Scatter和Gather的中文翻译 - - Scatter:分散; Gather:收集;
分散(scatter):是指从Channel中读取是指在读操作时将读取的数据写入多个buffer中(这里要注意:分散是指channel中的数据分散,也就是说被写入的多个buffer中,每一个buffer组成的数据都是不同的,所有的buffer数据组合起来才是channel的所有数据)。也就是从Channel中读取的数据“分散(scatter)”到多个Buffer中。
聚集(gather):
scatter / gather经常用于需要将传输的数据分开处理的场合,例如传输一个由消息头和消息体组成的消息,你可能会将消息体和消息头分散到不同的buffer中,这样你可以方便的处理消息头和消息体。
Scatter和Gather的实现是通过channel的read()和write()方法来实现的
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
/**
* Scatter : 将channel的数据分散写入到多个Buffer中(写入操作完毕之后,所有的buffer的数据加起来就是channel的数据)
* Gather : 是指在写操作时将多个buffer的数据写入同一个Channel,也就是从多个Buffer中的数据“聚集(gather)”后发送到Channel。
* @2017-3-22
*/
public class ScatterAndGather {
public static void main(String[] args) throws IOException {
File file = new File("F:/jia.txt");
FileInputStream fileInput = new FileInputStream(file);
FileChannel fileChannel = fileInput.getChannel();
ByteBuffer byteBuffer = ByteBuffer.allocate(48);
ByteBuffer byteBuffer1 = ByteBuffer.allocate(18);
ByteBuffer[] byteBuffers = {byteBuffer,byteBuffer1};
// 2、将Channel的数据写入到Buffer对象,这里返回的值是指写入到byteBuffer和byteBuffer1字节数的和(也就是写入到ByteBuffer数组的字节数)
long bytesRead = fileChannel.read(byteBuffers);
while (bytesRead != -1L) {
// 3、从写模式切换到读模式,想还原channel所有的数据可以按顺序读取ByteBuffer数组的所有Buffer对象,然后拼接起来。
byteBuffer.flip();
byteBuffer1.flip();
while (byteBuffer.hasRemaining()) {
System.out.print((char) byteBuffer.get());
}
System.out.println(" ----read " + bytesRead);
while (byteBuffer1.hasRemaining()) {
System.out.print((char) byteBuffer1.get());
}
System.out.println(" ----read111111 " + bytesRead);
// 4、清空Buffer对象缓冲区的所有数据
byteBuffer.clear();
byteBuffer1.clear();
// 再次将通道的数据写入到buffer中,这里返回的值是本次从通道读取的数据的字节数
bytesRead = fileChannel.read(byteBuffers);
}
}
}
其实Channel的Scatter/Gather与单个Buffer操作基本一致,只不过Scatter/Gather要在读写的时候操作多个对象(以数组的形式)