java NIO(十) 缓冲区——compact方法介绍


注意java6帮助文档对compact方法的介绍

compact
public abstract ByteBuffer compact()压缩此缓冲区(可选操作)。 
将缓冲区的<strong><em><u>当前位置和界限之间的字节(如果有)</u></em></strong>复制到缓冲区的开始处。即将索引 p = position() 处的字节复制到索引 0 处,将索引 p + 1 处的字节复制到索引 1 处,依此类推,直到将索引 limit() - 1 处的字节复制到索引 n = limit() - 1 - p 处。然后将缓冲区的位置设置为 n+1,并将其界限设置为其容量。如果已定义了标记,则丢弃它。 

将缓冲区的位置设置为复制的字节数,而不是零,以便调用此方法后可以紧接着调用另一个相对 put 方法。 

从缓冲区写入数据之后调用此方法,以防写入不完整。例如,以下循环语句通过 buf 缓冲区将字节从一个信道复制到另一个信道: 

 buf.clear();          // Prepare buffer for use
  while (in.read(buf) >= 0 || buf.position != 0) {
     buf.flip();
     out.write(buf);
     buf.compact();    // In case of partial write
 }
返回:
此缓冲区 
抛出: 
ReadOnlyBufferException - 如果此缓冲区是只读缓冲区

上文中的加黑加粗斜体部分表明了,为什么compact通常与flip方法合用:在通道(channel)间进行复制的时候,我们知道put或者get方法会通过标记pos的位置来标记字符位置,

flip在限制limit后,调用put方法(如上文中的例子),此时我们调用compact方法会执行两个动作,1、清除之前已经写如果的字符;2、根据上文加黑加粗斜体部分表明pos的位置将在0,通过这两步达到我们的预期,这就是为什么此时单纯的调用filp方法不行的原因。

下面通过两个图片形象说明compact的动作:

执行compact之前缓冲区在内存中的表现:


compact后缓冲区的表现:


由上图可看:分为两点:
1、释放一部分数据,即pos所指位置前移至零处;
2、重新填充,如果要重新填冲,pos的位置要慎重,这就是为什么最后pos的位置在4的原因
经过这两步之后形成所谓的压缩


下面再给出通道间复制字符串的代码:

package com.z;

import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;

public class ChannelCopy {
	
	public static void main(String[] args) throws Exception{
		
		ReadableByteChannel src = Channels.newChannel(System.in);
		WritableByteChannel des = Channels.newChannel(System.out);
		copy1(src,des);
		src.close();
		des.close();
	}
	
	private static void copy1(ReadableByteChannel src, WritableByteChannel des) throws Exception{
		
		ByteBuffer tmp = ByteBuffer.allocate(16 * 1024);
		while(src.read(tmp) != -1){
			tmp.flip();
			des.write(tmp);
			tmp.compact();
		}
		tmp.flip();
		while(tmp.hasRemaining()){
			des.write(tmp);
		}
	}

}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值