やんちのプログラミングメモ

こんにちは、こちらはやんちのウェブページです。
このページにはやんちがプログラミング中に使用するメモを載せて行く予定です。

JDK 1.4 から追加された java.nio.ByteBuffer の使い方のメモ

ByteBuffer とは?

JDK 1.4 から追加された、byte 配列のバッファを扱う用のクラス。
byteBuffer を扱うのに便利な機能が実装されている。

メモ

ByteBuffer には少し癖があるみたいなので、ポイントを抑えておこう。

まず、構造
属性として、「capacity/容量」、「limit/リミット」、「position/位置」
と言うのがある。
メソッドとして、「capacity()」、「clear()」、「flip()」、「limit()」、 「limit(int newLimit)」、「position()」、「position(int newPosition)」、 「rewind()」
と言うのがある。
(他のも属性やメソッドはあるが、詳しくは、Javadocを参照して下さい。)

ByteBuffer
- capacity: int
+ limit: int
+ position: int
...他
+ capacity(): int
+ clear():
+ flip():
+ limit(): int
+ limit(newLimit: int):
+ position(): int
+ position(newPosition: int):
+ rewind():
...他

属性から、解説していきます。

capacity/容量

capacity は、バッファ全体の容量を示しています。
capacity を指定するには、ByteBufferの初期化子allocate(int capacity)で インスタンス生成時に指定します。
インスタンス生成後、capacity は、読み取り専用となり、変更できません。
必要に応じて自動的に拡張されたりもしない模様。
capacity 値を取得するには、int capacity()メソッドを使用。

limit/リミット

バッファにデータを読み書きできる限界位置を示しています。
limit は capacity 以下の値となります。
int limit()メソッドで値の取得、 limit(int newLimit)メソッドで値の設定、ができる。

position/位置

データの読み書きを行う用の現在のカーソル位置です。
int position()メソッドで値の取得、 position(int newPosition)メソッドで値の設定、ができる

メソッドの解説。

int capacity()

capacity 値の取得。

clear()

ByteBuffer のクリア。
limit ← capacity、 position ← 0、とします。

flip()

ByteBuffer のフリップ。
limit ← position、 position ← 0、とします。

int limit()

limit 値の取得。

limit(int newLimit)

limit 値の設定

int position()

position 値の取得。

position(int newPosition)

position 値の設定。

rewind()

ByteBuffer のリワンド。
position ← 0、とします。
flip() メソッドとの違いは、limit 値を変更しない事。

使用例


インスタンス生成

// file:Test.java
import java.nio.ByteBuffer;

public class Test {
    public static void main(String[] args) {
        int capacity = 1024;
        ByteBuffer buffer = ByteBuffer.allocate(capacity);
    }
}

容量1024バイトの ByteBuffer インスタンスを生成

書き込み/読込み

ソース:
// file:Test.java
import java.nio.ByteBuffer;

public class Test {
    public static void main(String[] args) {
        
        // ByteBuffer のインスタンス生成
        int capacity = 1024;
        ByteBuffer buffer = ByteBuffer.allocate(capacity);
        
        // バッファにデータを書き込み
        buffer.clear();
        buffer.put(new byte[] {1, 2, 3, 4, 5});
        buffer.put(new byte[] {6, 7, 8, 9, 10});
        
        // バッファ内容を表示
        buffer.flip();
        int limit = buffer.limit();
        for (int i = 0; i < limit; i++) {
            System.out.printf("%04d:{%02x}\n", i, buffer.get());
        }
    }
}


実行結果:
0000:{01}
0001:{02}
0002:{03}
0003:{04}
0004:{05}
0005:{06}
0006:{07}
0007:{08}
0008:{09}
0009:{0a}


バッファ内容のコピー

ソース:
// file:Test.java
import java.nio.ByteBuffer;

public class Test {
    public static void main(String[] args) {
        
        // ByteBuffer のインスタンス生成
        ByteBuffer a = ByteBuffer.allocate(1024);
        ByteBuffer b = ByteBuffer.allocate(1024);
        
        // バッファにデータを書き込み
        a.clear();
        a.put(new byte[] {1, 2, 3, 4, 5});
        a.put(new byte[] {6, 7, 8, 9, 10});
        
        // バッファ内容をコピー
        ByteBuffer dest = b;    // コピー先の ByteBuffer
        ByteBuffer src = a;     // コピー元の ByteBuffer
        int dest_pos = 0;       // コピー先の位置
        int src_start = 3;      // コピー元の開始位置
        int src_end = 8;        // コピー元の終了位置
        copy(dest, src, dest_pos, src_start, src_end);
        
        // バッファ内容を表示
        b.flip();
        int limit = b.limit();
        for (int i = 0; i < limit; i++) {
            System.out.printf("%04d:{%02x}\n", i, b.get());
        }
    }
    
    public static void copy(ByteBuffer dest, ByteBuffer src, int dest_pos
            , int src_start, int src_end) {
        dest.clear();
        dest.position(dest_pos);
        src.position(src_start);
        src.limit(src_end);
        dest.put(src);
    }
}


実行結果:
0000:{04}
0001:{05}
0002:{06}
0003:{07}
0004:{08}


動作確認環境:
JDK 1.6.0_04
・2009-01-23