1.Scatter 从一个Channel读取的信息分散到N个缓冲区中(Buufer).
2.Gather 将N个Buffer里面内容按照顺序发送到一个Channel.
Scatter/Gather功能是通道(Channel)提供的 并不是Buffer,
Scatter/Gather相关接口 类图
ReadableByteChannel WritableByteChannel 接口提供了通道的读写功能
ScatteringByteChannel GatheringByteChannel接口都新增了两个以缓冲区数组作为参数的相应方法
以FileChannel为例
*Scatter
/** * 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缓冲区中的数据:qw System.out.println("head缓冲区中的数据:" + charset.decode(headBuffer)); bodyBuffer.flip(); //body缓冲区中的数据:ertyuiop System.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,bodyBuffer2 long n = channel.read(allBuffers, 0, 3); System.out.println("共读到多少字节:" + n); headBuffer.flip(); //head缓冲区中的数据:qw System.out.println("head缓冲区中的数据:" + charset.decode(headBuffer)); bodyBuffer1.flip(); //body1缓冲区中的数据:ert System.out.println("body1缓冲区中的数据:" + charset.decode(bodyBuffer1)); bodyBuffer2.flip(); //body2缓冲区中的数据:yu System.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(); }
private static Charset charset = Charset.forName("GBK"); 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
/** * 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顺序 写入abcdefg long 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 //最终写入abcdefg long n = channel.write(allBuffers, 0, 2); //应该返回7个字节 System.out.println("共写入多少字节:" + n); accessFile.close(); channel.close(); }
private static Charset charset = Charset.forName("GBK"); public static void main(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); }