2.4.3 視圖緩沖區(qū) 就像我們已經(jīng)討論的那樣,I/O 基本上可以歸結(jié)成組字節(jié)數(shù)據(jù)的四處傳遞。在進行大數(shù)據(jù)量的 I/O 操作時,很又可能您會使用各種ByteBuffer 類去讀取文件內(nèi)容,接收來自網(wǎng)絡連接的數(shù)據(jù),等等。一旦數(shù)據(jù)到達了您的 ByteBuffer ,您就需要查看它以決定怎么做或者在將它發(fā)送出去之前對它進行一些操作。ByteBuffer 類提供了豐富的 API 來創(chuàng)建視圖緩沖區(qū)。 視圖緩沖區(qū)通過已存在的緩沖區(qū)對象實例的工廠方法來創(chuàng)建。這種視圖對象維護它自己的屬性,容量,位置,上界和標記,但是和原來的緩沖區(qū)共享數(shù)據(jù)元素。我們已經(jīng)在 2.3 節(jié)見過了這樣的簡單例子,在例子中一個緩沖區(qū)被復制和切分。但是ByteBuffer 類允許創(chuàng)建視圖來將byte 型緩沖區(qū)字節(jié)數(shù)據(jù)映射為其它的原始數(shù)據(jù)類型。例如,asLongBuffer() 函數(shù)創(chuàng)建一個將八個字節(jié)型數(shù)據(jù)當成一個 long 型數(shù)據(jù)來存取的視圖緩沖區(qū)。 下面列出的每一個工廠方法都在原有的ByteBuffer 對象上創(chuàng)建一個視圖緩沖區(qū)。調(diào)用其中的任何一個方法都會創(chuàng)建對應的緩沖區(qū)類型,這個緩沖區(qū)是基礎(chǔ)緩沖區(qū)的一個切分,由基礎(chǔ)緩沖區(qū)的位置和上界決定。新的緩沖區(qū)的容量是字節(jié)緩沖區(qū)中存在的元素數(shù)量除以視圖類型中組成一個數(shù)據(jù)類型的字節(jié)數(shù)(參見表 2-1)。在切分中任一個超過上界的元素對于這個視圖緩沖區(qū)都是不可見的。視圖緩沖區(qū)的第一個元素從創(chuàng)建它的ByteBuffer 對象的位置開始(positon() 函數(shù)的返回值)。具有能被自然數(shù)整除的數(shù)據(jù)元素個數(shù)的視圖緩沖區(qū)是一種較好的實現(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)建了一個ByteBuffer 緩沖區(qū)的CharBuffer 視圖,如圖 Figure 2-16所示(Example 2-2 將這個框架用到了更大的范圍) - ByteBuffer byteBuffer = ByteBuffer.allocate (7).order(ByteOrder.BIG_ENDIAN);
- CharBuffer charBuffer = byteBuffer.asCharBuffer();
圖 2-16. 一個 ByteBuffer 的 CharBuffer 視圖
例 2-2. 創(chuàng)建一個 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() + "'");
- }
- }
運行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)建進一步的子視圖,就像 2.3 節(jié)所討論的那樣。 無論何時一個視圖緩沖區(qū)存取一個ByteBuffer 的基礎(chǔ)字節(jié),這些字節(jié)都會根據(jù)這個視圖緩沖區(qū)的字節(jié)順序設(shè)定被包裝成一個數(shù)據(jù)元素。當一個視圖緩沖區(qū)被創(chuàng)建時,視圖創(chuàng)建的同時它也繼承了基礎(chǔ)ByteBuffer 對象的字節(jié)順序設(shè)定。這個視圖的字節(jié)排序不能再被修改。在圖 2-16 中,您可以看到基礎(chǔ)ByteBuffer 對象中的兩個字節(jié)映射成CharBuffer 對象中的一個字符。字節(jié)順序設(shè)定決定了這些字節(jié)對是怎么樣被組合成字符型變量的。請參考2.4.1 節(jié)獲取更多詳細的解釋。 當直接從byte 型緩沖區(qū)中采集數(shù)據(jù)時,視圖換沖突擁有提高效率的潛能。如果這個視圖的字節(jié)順序和本地機器硬件的字節(jié)順序一致,低等級的(相對于高級語言而言)語言的代碼可以直接存取緩沖區(qū)中的數(shù)據(jù)值,而不是通過比特數(shù)據(jù)的包裝和解包裝過程來完成。 Java nio入門教程詳解(十)
0
0
我們認為:用戶的主要目的,是為了獲取有用的信息,而不是來點擊廣告的。因此本站將竭力做好內(nèi)容,并將廣告和內(nèi)容進行分離,確保所有廣告不會影響到用戶的正常閱讀體驗。用戶僅憑個人意愿和興趣愛好點擊廣告。
我們堅信:只有給用戶帶來價值,用戶才會給我們以回報。
|