高性能なbyte型のコンテナクラス
生成
- allocate
public static ByteBuffer allocate(int capacity)
- allocateDirect
public static ByteBuffer allocateDirect(int capacity)
- wrap
public static ByteBuffer wrap(byte[] array) throws IndexOutOfBoundsException
ByteBufferオブジェクトを生成するにはstaticメソッドのallocateを使用します。引数のcapacityはバッファの容量です。
New I/Oでは、Javaのヒープ外にバッファの割り当てを行うダイレクトバッファを使用できます。これを生成するにはallocateDirectメソッドを使用します。
ダイレクトバッファの生成はByteBufferクラスしか行えませんが、他のバッファへの変換メソッドasXXXXBuffer (XXXXはプリミティブ型名) を使用することで、他のバッファでもダイレクトバッファを使用することができます。
wrapメソッドは引数のbyte配列を使用してバッファを生成します。生成されたバッファは内部の要素として引数の配列を使用するため、要素を変更するとbyte配列も変更されます。また、byte列に変更を加えると、バッファもそれに応じて変更されます。
リスト1に3種類の生成例を示しました。
// 容量が10のバッファ ByteBuffer buffer = ByteBuffer.allocate(10); // 容量が10のダイレクトバッファ ByteBuffer directBuffer = ByteBuffer.allocateDirect(10); // 配列を使用したバッファの生成 byte[] array = new byte[]{0x01, 0x02, 0x03, 0x04}; ByteBuffer buffer2 = ByteBuffer.wrap(array);
position, limitに関する操作
- Buffer#position
public int position()
public Buffer position(int newPosition)
- Buffer#limit
public int limit()
public Buffer limit(int newLimit)
- Buffer#clear
public Buffer clear()
- Buffer#flip
public Buffer flip()
バッファは図1に示した3つのプロパティを持ちます。
positionは要素のアクセス位置を示します。読み込み・書き込みを行うと、そのデータ量に応じてpositionが移動します。
positionの最大値がlimitです。capacityはバッファの容量を表します。したがって、これらの関係は0 <= position <= limit <= capacityとなります。
capacityは不変ですが、limitとpositionは変更できます。positionメソッド、limitメソッドとも引数がない場合は値を取得、intの引数がある場合は値を設定します。ただし、上述の関係を破るような値を設定するとIllegalArgumentException例外が発生します。
これ以外にもposition、limitを操作するメソッドがあります。clearメソッドはプロパティの初期化、つまりposition=0、limit=capacityとします(図2)。flipメソッドはlimitをpositionの値として、positionは0にします(図3)。この2つのメソッドの使用例はByteChannelインタフェースの使用例を参照してください。
要素へのアクセス
- get
public byte get()
public ByteBuffer get(byte[] dst)
public ByteBuffer get(byte[] dst, int offset, int length)
public ByteBuffer get(int index)
- put
public ByteBuffer put(byte b)
public ByteBuffer put(byte[] src)
public ByteBuffer put(byte[] srt, int offset, int length)
public ByteBuffer put(ByteBuffer src)
public ByteBuffer put(int index, byte b)
バッファの要素を読み込むには get メソッドを使用します。getメソッドは引数の違いにより4種類ありますが、シーケンシャルアクセスを行うものと、ランダムアクセスを行うものに大別できます。シーケンシャルアクセスは引数にindexがないものです。
シーケンシャルアクセスではpositionから読み込みを行います。引数のない場合、1バイト読み込み、positionを1進めます。
引数が配列のみの場合、配列の長さ分読み込み、positionをその分進めます。offsetとlengthが指定してある場合、positionの位置からlengthバイトを読み込み、dst[offset]から格納します。positionはlength分進みます。
ランダムアクセスを行うものは引数にindexがあるgetメソッドです。indexの位置の要素を1バイト読み込みますが、positionは変更しません。
書き込みもgetメソッドと同様にシーケンシャルアクセスとランダムアクセスに大別できます。
bが引数のputメソッドは、position位置にbを書き込み、positionを1進めます。byte配列が引数のものは、配列の内容をバッファに書き込みます。positionは配列長進みます。offsetとlengthが指定されている場合は、dst[offset]からlengthバイト書き込みます。positionはlength進みます。
ByteBufferオブジェクトのsrcが引数の場合、srcのpositionからlimitまでの要素を書き込みます。positionはsrcのlimit-position分だけ進みます。
引数にindexを使用しているのが、ランダムアクセスのputメソッドです。indexの位置にbを書き込みますが、positionは変化しません。
(2003.03)