JAVA NIO Scatter/Gather(矢量IO)

矢量IO=Scatter/Gather:
 
在多个缓冲区上实现一个简单的IO操作。减少或避免了缓冲区拷贝和系统调用(IO)
 
write:Gather
数据从几个缓冲区顺序抽取并沿着通道发送,就好比全部缓冲区全部连接起来放入一个大的缓冲区进行发送,缓冲区本身不具备gather能力。
read:Scatter

从通道读取的数据会按顺序散布到多个缓冲区,直到缓冲区被填满或者通道数据读完。


 

 

Gather:
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(“头缓冲区中的数据:”  + charset.decode(headBuffer));  
      
    bodyBuffer.flip();  
    // body缓冲区中的数据:ertyuiop  
    System.out.println(“body缓冲区中的数据:”  + charset.decode(bodyBuffer));  
    accessFile.close();  
    channel.close();  
}  
  
/ ** 
 *散点2 
 * <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  
    长 N = channel.read(allBuffers,  0 ,  3 );  
      
    System.out.println(“共读到多少字节:”  + n);  
      
    headBuffer.flip();  
    // head缓冲区中的数据:qw  
    System.out.println(“头缓冲区中的数据:”  + 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个字节数据以便测试分散模式  
    writeData(fileName,  “qwertyuiop” );  
      
    /** - - - - - 分散 - - - - - - */  
    // read(java.nio.ByteBuffer [])  
    scatter(fileName);  
      
    // read(java.nio.ByteBuffer [],int,int)  
    scatter2(fileName);  
}  

/ ** 
 *聚集 
 * <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  collect2(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  
    长 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” ;  
    /** - - - - - 收集 - - - - - - */  
    // FileChannel#write(java.nio.ByteBuffer [])  
    gather(fileName);  
      
    // FileChannel#write(java.nio.ByteBuffer [],int,int)  
    gather2(fileName);  
}  



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值