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);
		}
	}

}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章