[index]
[top]
[bottom]

java.nio.Buffer

java.nio.Bufferクラスは、便利なクラスなのですが、操作の方法が少々分かりにくいので、簡単にまとめてみました。サンプルはByteBufferを使用していますが、他のBufferでも基本的には同じです。

Bufferの作成

Bufferを新規に作成するには、allocate(int capacity)メソッドを使用します。下記のコードは、10バイトの容量を持つByteBufferを作成します。

ByteBufferの作成
ByteBuffer buffer = ByteBuffer.allocate(10);

Bufferの操作

Bufferには、いくつかの重要な値があります。capacity・limit・positionがそれです。以下のメソッドで、それぞれの値の取得や変更を行うことができます。

capacity()

Bufferの容量を返します。容量は、このBufferに格納できる最大のサイズです。ByteBufferの場合は、バイト数になります。容量は変更できません。

limit()/limit(int)

Bufferの制限値を返します。制限値は、このBufferに格納できる最大のサイズです。制限値は、容量の範囲内で変更可能です。

position()/position(int)

Bufferの現在の位置を返します。位置は、相対的な格納や取得で使用されます。位置は、リミットの範囲内で変更可能です。

初期状態

先ほどのallocateメソッドでアロケートした直後のBufferは、capacity()が10を、limit()が10を、position()が0をそれぞれ返します。

ByteBuffer作成時の、初期値
position()
limit()
capacity()
Index012345 678910
ByteBuffer0x000x000x000x000x000x00 0x000x000x000x00

相対的な格納(put)

相対的な格納動作は、Bufferのposition()が指す位置から、指定の値を格納します。position()は、格納した内容のバイト数分移動します。

4バイトの配列を相対的に格納
byte[] bytes = "1234".getBytes();
buffer.put(bytes);
position()
limit()
capacity()
Index012345 678910
ByteBuffer0x310x320x330x340x000x00 0x000x000x000x00
2バイトの数値を相対的に格納
buffer.putShort(54321);
position()
limit()
capacity()
Index012345 678910
ByteBuffer0x310x320x330x340xD40x31 0x000x000x000x00

気をつけなければいけないのは、リミットを越えて(リミットの位置に)データを格納することができないということです。上の例で言えば、2バイトの数値を格納した後、5バイト以上のデータ(例えばlong)を格納しようとすると、java.nio.BufferUnderflowExceptionが発生します。

相対的な取得(get)とその前に

相対的な取得動作は、ByteBufferのposition()が指す位置から、指定のデータ型の値を取得します。

そのためには、当然位置を変更する必要があります。複数回のput()で編集したBufferから、一括でデータを取得したい場合に、便利なメソッドが容易されています。

flip()です。このメソッドは、リミットをポジションの位置に移動し、ポジションを先頭(0)に移動します。

2バイトの数値を相対的に格納
position()
limit()
capacity()
Index012345 678910
ByteBuffer0x310x320x330x340xD40x31 0x000x000x000x00
buffer.flip();
position()
limit()
capacity()
Index012345 678910
ByteBuffer0x310x320x330x340xD40x31 0x000x000x000x00

この状態で適切なサイズのbyte配列を作成し、get()を行うことで全てのデータを取得できます。

byte配列を作成し、get()
byte[] tmpBuf = new byte[buffer.limit()];  // 6バイト分の配列が作成される
buffer.get(tmpBuf);
position()
limit()
capacity()
Index012345 678910
ByteBuffer0x310x320x330x340xD40x31 0x000x000x000x00
 
tmpBuf012345
0x310x320x330x340xD40x31

絶対的な取得

相対的な操作と違い、絶対的な操作は、現在位置に関係なく、指定のインデックスが指す位置から、指定のデータ型の値を取得します。

この操作では、現在位置などの内容は変化しません。

位置を指定しての取得
position()
limit()
capacity()
Index012345 678910
ByteBuffer0x310x320x330x340xD40x31 0x000x000x000x00
buffer.getShort(4);  // 54321(0xD431)が返ります