NIO - Scatter/Gather

转自: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缓冲区中的数据: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();
	}
	
	
	
	
	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顺序  写入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();
	}


	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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值