NIO - Scatter/Gather

来源:互联网 发布:easygen3200软件下载 编辑:程序博客网 时间:2024/06/05 16:45

转自:http://blog.csdn.net/java2000_wl/article/details/7619395

1.Scatter 从一个Channel读取的信息分散到N个缓冲区中(Buufer).

2.Gather 将N个Buffer里面内容按照顺序发送到一个Channel.

Scatter/Gather功能是通道(Channel)提供的 并不是Buffer,

Scatter/Gather相关接口 类图

ReadableByteChannel WritableByteChannel 接口提供了通道的读写功能

ScatteringByteChannel GatheringByteChannel接口都新增了两个以缓冲区数组作为参数的相应方法

以FileChannel为例

*Scatter


package com.zhilong.nio.example;import java.io.IOException;import java.io.RandomAccessFile;import java.nio.ByteBuffer;import java.nio.channels.FileChannel;import java.nio.charset.Charset;public class ScatterGatherTest {private static Charset charset = Charset.forName("GBK");    /** * Scatter * <br>------------------------------<br> * @param fileName * @throws IOException * @see FileChannel.read(java.nio.ByteBuffer[]) */private static void scatter(final String fileName) throws IOException {RandomAccessFile accessFile = new RandomAccessFile(fileName, "r");//获取文件通道FileChannel channel = accessFile.getChannel();//创建两个缓冲区ByteBuffer headBuffer = ByteBuffer.allocate(2);ByteBuffer bodyBuffer = ByteBuffer.allocate(1024);ByteBuffer[] allBuffers = new ByteBuffer[]{headBuffer, bodyBuffer};// headBuffer 前10个字节// bodyBuffer 剩下的 long n = channel.read(allBuffers);System.out.println("共读到多少字节:" + n);headBuffer.flip();//head缓冲区中的数据:qwSystem.out.println("head缓冲区中的数据:" + charset.decode(headBuffer));bodyBuffer.flip();//body缓冲区中的数据:ertyuiopSystem.out.println("body缓冲区中的数据:" + charset.decode(bodyBuffer));accessFile.close();channel.close();}/** * Scatter2 * <br>------------------------------<br> * @param fileName * @throws IOException * @see FileChannel.read(java.nio.ByteBuffer[], int, int) */private static void scatter2(final String fileName) throws IOException {RandomAccessFile accessFile = new RandomAccessFile(fileName, "r");//获取文件通道FileChannel channel = accessFile.getChannel();//创建五个缓冲区ByteBuffer headBuffer = ByteBuffer.allocate(2);ByteBuffer bodyBuffer1 = ByteBuffer.allocate(3);ByteBuffer bodyBuffer2 = ByteBuffer.allocate(2);ByteBuffer bodyBuffer3 = ByteBuffer.allocate(2);ByteBuffer bodyBuffer4 = ByteBuffer.allocate(1);ByteBuffer[] allBuffers = new ByteBuffer[]{headBuffer, bodyBuffer1, bodyBuffer2,bodyBuffer3, bodyBuffer4,};//0从那个缓冲区开始被使用    使用3个缓冲区//会使用 headBuffer,bodyBuffer1,bodyBuffer2long n = channel.read(allBuffers, 0, 3);System.out.println("共读到多少字节:" + n);headBuffer.flip();//head缓冲区中的数据:qwSystem.out.println("head缓冲区中的数据:" + charset.decode(headBuffer));bodyBuffer1.flip();//body1缓冲区中的数据:ertSystem.out.println("body1缓冲区中的数据:" + charset.decode(bodyBuffer1));bodyBuffer2.flip();//body2缓冲区中的数据:yuSystem.out.println("body2缓冲区中的数据:" + charset.decode(bodyBuffer2));bodyBuffer3.flip();//body3,没有数据System.out.println("body3缓冲区中的数据:" + charset.decode(bodyBuffer3));bodyBuffer4.flip();//body4没有数据System.out.println("body4缓冲区中的数据:" + charset.decode(bodyBuffer4));accessFile.close();channel.close();}/** * * <br>------------------------------<br> * @param fileName * @throws IOException */private static void writeData(final String fileName, String data) throws IOException {RandomAccessFile accessFile = new RandomAccessFile(fileName, "rw");accessFile.writeBytes(data);accessFile.close();}public static void main(String[] args) throws IOException {final String fileName = "D:/test.log";//先写入10个字节数据 以便测试 scatter模式writeData(fileName, "qwertyuiop");/**----------Scatter------------*///read(java.nio.ByteBuffer[])scatter(fileName);//read(java.nio.ByteBuffer[], int, int)scatter2(fileName);}/** * gather * <br>------------------------------<br> * @param fileName * @throws IOException  * @see FileChannel#write(java.nio.ByteBuffer[]) */private static void gather(String fileName) throws IOException {RandomAccessFile accessFile = new RandomAccessFile(fileName, "rw");//获取文件通道FileChannel channel = accessFile.getChannel();//创建两个缓冲区ByteBuffer headBuffer = ByteBuffer.allocate(3);headBuffer.put("abc".getBytes());ByteBuffer bodyBuffer = ByteBuffer.allocate(1024);bodyBuffer.put("defg".getBytes());ByteBuffer[] allBuffers = new ByteBuffer[]{headBuffer, bodyBuffer};headBuffer.flip();bodyBuffer.flip();//将按allBuffers顺序  写入abcdefglong n = channel.write(allBuffers);System.out.println("共写入多少字节:" + n);accessFile.close();channel.close();}/** * gather2 * <br>------------------------------<br> * @param fileName * @throws IOException  * @see FileChannel#write(java.nio.ByteBuffer[], int, int) */private static void gather2(String fileName) throws IOException {RandomAccessFile accessFile = new RandomAccessFile(fileName, "rw");//获取文件通道FileChannel channel = accessFile.getChannel();//创建两个缓冲区ByteBuffer headBuffer = ByteBuffer.allocate(3);ByteBuffer bodyBuffer1 = ByteBuffer.allocate(4);ByteBuffer bodyBuffer2 = ByteBuffer.allocate(20);ByteBuffer bodyBuffer3 = ByteBuffer.allocate(20);ByteBuffer bodyBuffer4 = ByteBuffer.allocate(20);headBuffer.put("abc".getBytes());bodyBuffer1.put("defg".getBytes());bodyBuffer2.put("bnbnbnb".getBytes());bodyBuffer3.put("zzz444".getBytes());ByteBuffer[] allBuffers = new ByteBuffer[]{headBuffer, bodyBuffer1, bodyBuffer2,bodyBuffer3, bodyBuffer4,};headBuffer.flip();bodyBuffer1.flip();bodyBuffer2.flip();bodyBuffer3.flip();bodyBuffer4.flip();//将按allBuffers数组顺序使用两个缓冲区//0从哪开始//2使用几个//当前使用headBuffer  bodyBuffer1//最终写入abcdefglong n = channel.write(allBuffers, 0, 2);//应该返回7个字节System.out.println("共写入多少字节:" + n);accessFile.close();channel.close();}public static void main1(String[] args) throws IOException {final String fileName = "D:/test.log";/**----------Gather------------*///FileChannel#write(java.nio.ByteBuffer[])gather(fileName);//FileChannel#write(java.nio.ByteBuffer[], int, int)gather2(fileName);}}


0 0