2.4.3 視圖緩沖區(qū) 就像我們已經(jīng)討論的那樣,I/O 基本上可以歸結(jié)成組字節(jié)數(shù)據(jù)的四處傳遞。在進(jìn)行大數(shù)據(jù)量的 I/O 操作時(shí),很又可能您會(huì)使用各種ByteBuffer 類去讀取文件內(nèi)容,接收來自網(wǎng)絡(luò)連接的數(shù)據(jù),等等。一旦數(shù)據(jù)到達(dá)了您的 ByteBuffer ,您就需要查看它以決定怎么做或者在將它發(fā)送出去之前對(duì)它進(jìn)行一些操作。ByteBuffer 類提供了豐富的 API 來創(chuàng)建視圖緩沖區(qū)。 視圖緩沖區(qū)通過已存在的緩沖區(qū)對(duì)象實(shí)例的工廠方法來創(chuàng)建。這種視圖對(duì)象維護(hù)它自己的屬性,容量,位置,上界和標(biāo)記,但是和原來的緩沖區(qū)共享數(shù)據(jù)元素。我們已經(jīng)在 2.3 節(jié)見過了這樣的簡(jiǎn)單例子,在例子中一個(gè)緩沖區(qū)被復(fù)制和切分。但是ByteBuffer 類允許創(chuàng)建視圖來將byte 型緩沖區(qū)字節(jié)數(shù)據(jù)映射為其它的原始數(shù)據(jù)類型。例如,asLongBuffer() 函數(shù)創(chuàng)建一個(gè)將八個(gè)字節(jié)型數(shù)據(jù)當(dāng)成一個(gè) long 型數(shù)據(jù)來存取的視圖緩沖區(qū)。 下面列出的每一個(gè)工廠方法都在原有的ByteBuffer 對(duì)象上創(chuàng)建一個(gè)視圖緩沖區(qū)。調(diào)用其中的任何一個(gè)方法都會(huì)創(chuàng)建對(duì)應(yīng)的緩沖區(qū)類型,這個(gè)緩沖區(qū)是基礎(chǔ)緩沖區(qū)的一個(gè)切分,由基礎(chǔ)緩沖區(qū)的位置和上界決定。新的緩沖區(qū)的容量是字節(jié)緩沖區(qū)中存在的元素?cái)?shù)量除以視圖類型中組成一個(gè)數(shù)據(jù)類型的字節(jié)數(shù)(參見表 2-1)。在切分中任一個(gè)超過上界的元素對(duì)于這個(gè)視圖緩沖區(qū)都是不可見的。視圖緩沖區(qū)的第一個(gè)元素從創(chuàng)建它的ByteBuffer 對(duì)象的位置開始(positon() 函數(shù)的返回值)。具有能被自然數(shù)整除的數(shù)據(jù)元素個(gè)數(shù)的視圖緩沖區(qū)是一種較好的實(shí)現(xiàn)。 - public abstract class ByteBuffer extends Buffer implements Comparable
- {
- // 這里僅列出部分API
- public abstract CharBuffer asCharBuffer();
- public abstract ShortBuffer asShortBuffer();
- public abstract IntBuffer asIntBuffer();
- public abstract LongBuffer asLongBuffer();
- public abstract FloatBuffer asFloatBuffer();
- public abstract DoubleBuffer asDoubleBuffer();
- }
下面的代碼創(chuàng)建了一個(gè)ByteBuffer 緩沖區(qū)的CharBuffer 視圖,如圖 Figure 2-16所示(Example 2-2 將這個(gè)框架用到了更大的范圍) - ByteBuffer byteBuffer = ByteBuffer.allocate (7).order(ByteOrder.BIG_ENDIAN);
- CharBuffer charBuffer = byteBuffer.asCharBuffer();
圖 2-16. 一個(gè) ByteBuffer 的 CharBuffer 視圖
例 2-2. 創(chuàng)建一個(gè) ByteBuffer 的字符視圖 - package com.ronsoft.books.nio.buffers;
- import java.nio.Buffer;
- import java.nio.ByteBuffer;
- import java.nio.CharBuffer;
- import java.nio.ByteOrder;
- /**
- * Test asCharBuffer view.
- *
- * Created May 2002
- * @author Ron Hitchens (ron@ronsoft.com)
- */
- public class BufferCharView
- {
- public static void main (String [] argv) throws Exception
- {
- ByteBuffer byteBuffer = ByteBuffer.allocate(7).order (ByteOrder.BIG_ENDIAN);
- CharBuffer charBuffer = byteBuffer.asCharBuffer( );
- // Load the ByteBuffer with some bytes
- byteBuffer.put (0, (byte)0);
- byteBuffer.put (1, (byte)'H');
- byteBuffer.put (2, (byte)0);
- byteBuffer.put (3, (byte)'i');
- byteBuffer.put (4, (byte)0);
- byteBuffer.put (5, (byte)'!');
- byteBuffer.put (6, (byte)0);
- println (byteBuffer);
- println (charBuffer);
- }
- // Print info about a buffer
- private static void println (Buffer buffer)
- {
- System.out.println ("pos=" + buffer.position() + ", limit=" + buffer.limit() + ", capacity=" + buffer.capacity() + ": '" + buffer.toString() + "'");
- }
- }
運(yùn)行BufferCharView程序的輸出是: pos=0, limit=7, capacity=7: 'java.nio.HeapByteBuffer[pos=0 lim=7 cap=7]'
pos=0, limit=3, capacity=3: 'Hi! 一旦您得到了視圖緩沖區(qū),您可以用duplicate() , slice() 和asReadOnlyBuffer() 函數(shù)創(chuàng)建進(jìn)一步的子視圖,就像 2.3 節(jié)所討論的那樣。 無論何時(shí)一個(gè)視圖緩沖區(qū)存取一個(gè)ByteBuffer 的基礎(chǔ)字節(jié),這些字節(jié)都會(huì)根據(jù)這個(gè)視圖緩沖區(qū)的字節(jié)順序設(shè)定被包裝成一個(gè)數(shù)據(jù)元素。當(dāng)一個(gè)視圖緩沖區(qū)被創(chuàng)建時(shí),視圖創(chuàng)建的同時(shí)它也繼承了基礎(chǔ)ByteBuffer 對(duì)象的字節(jié)順序設(shè)定。這個(gè)視圖的字節(jié)排序不能再被修改。在圖 2-16 中,您可以看到基礎(chǔ)ByteBuffer 對(duì)象中的兩個(gè)字節(jié)映射成CharBuffer 對(duì)象中的一個(gè)字符。字節(jié)順序設(shè)定決定了這些字節(jié)對(duì)是怎么樣被組合成字符型變量的。請(qǐng)參考2.4.1 節(jié)獲取更多詳細(xì)的解釋。 當(dāng)直接從byte 型緩沖區(qū)中采集數(shù)據(jù)時(shí),視圖換沖突擁有提高效率的潛能。如果這個(gè)視圖的字節(jié)順序和本地機(jī)器硬件的字節(jié)順序一致,低等級(jí)的(相對(duì)于高級(jí)語言而言)語言的代碼可以直接存取緩沖區(qū)中的數(shù)據(jù)值,而不是通過比特?cái)?shù)據(jù)的包裝和解包裝過程來完成。 Java nio入門教程詳解(十)
0
0
我們認(rèn)為:用戶的主要目的,是為了獲取有用的信息,而不是來點(diǎn)擊廣告的。因此本站將竭力做好內(nèi)容,并將廣告和內(nèi)容進(jìn)行分離,確保所有廣告不會(huì)影響到用戶的正常閱讀體驗(yàn)。用戶僅憑個(gè)人意愿和興趣愛好點(diǎn)擊廣告。
我們堅(jiān)信:只有給用戶帶來價(jià)值,用戶才會(huì)給我們以回報(bào)。
|