天天看點

NIO入門系列之第二章:通道和緩沖區第2章 通道和緩沖區

通道和緩沖區是 NIO 中的核心對象,幾乎在每一個I/O 操作中都要使用它們。

通道是對原 I/O 包中的流的模拟。到任何目的地(或來自任何地方)的所有資料都必須通過一個 Channel 對象。一個 Buffer 實質上是一個容器對象。發送給一個通道的所有對象都必須首先放到緩沖區中;同樣地,從通道中讀取的任何資料都要讀到緩沖區中。

Buffer 是一個對象,它包含一些要寫入或者剛讀出的資料。在 NIO 中加入 Buffer 對象,展現了新庫與原 I/O 的一個重要差別。在面向流的 I/O 中,您将資料直接寫入或者将資料直接讀到 Stream 對象中。

在 NIO 庫中,所有資料都是用緩沖區處理的。在讀取資料時,它是直接讀到緩沖區中的。在寫入資料時,它是寫入到緩沖區中的。任何時候通路 NIO 中的資料,您都是将它放到緩沖區中。

緩沖區實質上是一個數組。通常它是一個位元組數組,但是也可以使用其他種類的數組。但是一個緩沖區不僅僅是一個數組。緩沖區提供了對資料的結構化通路,而且還可以跟蹤系統的讀/寫程序。

最常用的緩沖區類型是 ByteBuffer。一個 ByteBuffer 可以在其底層位元組數組上進行 get/set 操作(即位元組的擷取和設定)。

ByteBuffer 不是 NIO 中唯一的緩沖區類型。事實上,對于每一種基本 Java 類型都有一種緩沖區類型:

ByteBuffer

CharBuffer

ShortBuffer

IntBuffer

LongBuffer

FloatBuffer

DoubleBuffer

每一個 Buffer 類都是 Buffer 接口的一個執行個體。除了 ByteBuffer,每一個 Buffer 類都有完全一樣的操作,隻是它們所處理的資料類型不一樣。因為大多數标準I/O 操作都使用ByteBuffer,是以它具有所有共享的緩沖區操作以及一些特有的操作。

現在您可以花一點時間運作 UseFloatBuffer.java,它包含了類型化的緩沖區的一個應用例子。

<code>import</code> <code>java.nio.*;</code>

<code>public</code> <code>class</code> <code>UseFloatBuffer</code>

<code>{</code>

<code>  </code><code>static</code> <code>public</code> <code>void</code> <code>main( String args[] ) </code><code>throws</code> <code>Exception {</code>

<code>    </code><code>FloatBuffer buffer = FloatBuffer.allocate( </code><code>10</code> <code>);</code>

<code>    </code><code>for</code> <code>(</code><code>int</code> <code>i=</code><code>0</code><code>; i&lt;buffer.capacity(); ++i) {</code>

<code>      </code><code>float</code> <code>f = (</code><code>float</code><code>)Math.sin( (((</code><code>float</code><code>)i)/</code><code>10</code><code>)*(</code><code>2</code><code>*Math.PI) );</code>

<code>      </code><code>buffer.put( f );</code>

<code>    </code><code>}</code>

<code>    </code><code>buffer.flip();</code>

<code>    </code><code>while</code> <code>(buffer.hasRemaining()) {</code>

<code>      </code><code>float</code> <code>f = buffer.get();</code>

<code>      </code><code>System.out.println( f );</code>

<code>  </code><code>}</code>

<code>}</code>

Channel是一個對象,可以通過它讀取和寫入資料。拿 NIO 與原來的 I/O 做個比較,通道就像是流。

正如前面提到的,所有資料都通過 Buffer 對象來處理。您永遠不會将位元組直接寫入通道中,相反,您是将資料寫入包含一個或者多個位元組的緩沖區。同樣,您不會直接從通道中讀取位元組,而是将資料從通道讀入緩沖區,再從緩沖區擷取這個位元組。

通道與流的不同之處在于通道是雙向的。而流隻是在一個方向上移動(一個流必須是InputStream 或者 OutputStream的子類),而通道可以用于讀、寫或者同時用于讀寫。

因為它們是雙向的,是以通道可以比流更好地反映底層作業系統的真實情況。特别是在 UNIX 模型中,底層作業系統通道是雙向的。

本文轉自 夢朝思夕 51CTO部落格,原文連結:http://blog.51cto.com/qiangmzsx/1409428

繼續閱讀