天天看點

給你的流添加緩沖裝置——位元組塊ByteChunk

這是一個很重要的一個位元組數組處理緩沖工具,它封裝了位元組緩沖器及對位元組緩沖區的操作,包括對緩沖區的寫入、讀取、擴充緩沖區大小等等,另外還提供相應字元編碼的轉碼操作。此工具讓緩沖操作變得更加友善,除了緩沖區他還有兩個channel——ByteInputChannel和ByteOutputChannel,這兩個通道一個用于輸入讀取資料,一個用于輸出資料,并且會自動判斷緩沖區是否超出規定的緩沖大小,一旦超出則把緩沖區資料全部輸出。

給你的流添加緩沖裝置——位元組塊ByteChunk

如上圖,緩沖區buf負責存放待輸出的位元組數組,此區域有初始值及最大值,在運作時會根據實際進行擴充,一旦到達最大值則馬上輸出到指定目标。此外還定義了兩個内部接口——ByteInputChannel和ByteOutputChannel,一般可以認為一個用于讀取資料一個用于輸出資料。另外它還包含Chartset對象,有了它可以友善轉碼工作。下面用一個簡化例子說明位元組塊的工作機制,受篇幅影響,為使例子簡潔這裡省去了很多方法和Chartset對象,隻展示緩沖的工作機制。

①   位元組塊ByteChunk的簡潔實作,包含資料讀取輸出接口、記憶體配置設定方法allocate、緩沖區添加位元組方法append、緩沖區擴容方法makeSpace及重新整理緩沖區方法flushBuffer。

public final class ByteChunk {

       public static interface ByteInputChannel{

                public int realReadBytes(bytecbuf[], int off, int len)

                                   throwsIOException;

       }

       public static interface ByteOutputChannel{

                public void realWriteBytes(bytecbuf[], int off, int len)

       private byte[] buff;

       private int start = 0;

       private int end;

       private int limit = -1;

       private ByteInputChannel in = null;

       private ByteOutputChannel out = null;

       public ByteChunk() {

       public void allocate(int initial, intlimit) {

                if (buff == null || buff.length< initial) {

                         buff = newbyte[initial];

                }

                this.limit = limit;

                start = 0;

                end = 0;

       public void setByteInputChannel(ByteInputChannelin) {

                this.in = in;

       public voidsetByteOutputChannel(ByteOutputChannel out) {

                this.out = out;

       public void append(byte b) throwsIOException {

                makeSpace(1);

                if (limit > 0 && end>= limit) {

                         flushBuffer();

                buff[end++]= b;

       public void flushBuffer() throwsIOException {

                out.realWriteBytes(buff, start,end - start);

                end = start;

       private void makeSpace(int count) {

                byte[] tmp = null;

                int newSize= buff.length * 2;

                if (limit > 0 &&newSize > limit) {

                         newSize = limit;

                tmp = new byte[newSize];

                System.arraycopy(buff, start,tmp, 0, end - start);

                buff = tmp;

                tmp = null;

                end = end - start;

}

②   輸出測試類OutputBuffer,此類使用位元組塊提供的緩沖機制對d盤的hello.txt檔案進行寫入操作,為更好說明緩沖區工作原理,把位元組塊的緩沖區初始大小設為3最大為7,我們要把八個位元組碼寫到hello.txt檔案,主要看加粗的三行代碼,執行dowrite方法時因為長度為8,已經超過了緩沖區最大值,是以進行了一次真實寫入操作,接着讓程式睡眠十秒,期間你打開hello.txt檔案隻能看到7個位元組數組,它們為1到7(使用十六進制打開)。十秒過後,由于執行了flush重新整理操作才把剩下的一個位元組寫入檔案。

public class OutputBuffer implements ByteChunk.ByteOutputChannel{

       private ByteChunk fileBuffer;

       FileOutputStream fileOutputStream;

       public OutputBuffer() {

                fileBuffer = new ByteChunk();

                fileBuffer.setByteOutputChannel(this);

                fileBuffer.allocate(3, 7);

                try {

                         fileOutputStream = newFileOutputStream("d:\\hello.txt");

                } catch (FileNotFoundExceptione) {

                         e.printStackTrace();

       public void realWriteBytes(byte cbuf[],int off, int len)

                         throws IOException {

                fileOutputStream.write(cbuf,off, len);

       public void flush() throws IOException {

                fileBuffer.flushBuffer();

       public int dowrite(byte[] bytes) throwsIOException {

                for (int i = 0; i <bytes.length; i++)

                         fileBuffer.append(bytes[i]);

                return bytes.length;

       public static void main(String[] args)throws InterruptedException {

                OutputBuffer outputBuffer = newOutputBuffer();

                byte[] bytes = { 1, 2, 3, 4, 5,6, 7, 8 };

                         outputBuffer.dowrite(bytes);

                         Thread.currentThread().sleep(10*1000);

                         outputBuffer.flush();

                } catch (IOException e) {

位元組塊是一個很有用的工具類,它提供了緩沖工具友善我們對某些流添加緩沖區,類似的工具還有字元塊CharChunk,顧名思義它是專門用為字元類型的資料提供緩沖操作。

<a target="_blank" href="https://item.jd.com/12185360.html">點選訂購作者《Tomcat核心設計剖析》</a>

繼續閱讀