プロジェクト

全般

プロフィール

Javaプログラミング バッファ操作

NIOのバッファ概要

Java SEのNIO(New I/O)ライブラリでバッファリングやデータ変換を提供するAPIです。

バッファはプリミティブ型に対応するByteBuffer、CharBuffer、ShortBuffer、IntBuffer、LongBuffer、FloatBuffer、DoubleBufferが用意されています。
バッファには、容量、リミット、位置、マークが存在し、0≦マーク≦位置≦リミット≦容量となる不変項が存在します。

バッファの生成メソッドは、allocate、duplicate、slice、wrap などです。

バッファに格納されたデータの操作は、相対get/put、絶対get/putがあります。
前者は、位置に対して読み書きを行い、読み書きした項目数分位置を進めます。
後者は、位置に依存せず、指定したindexの場所を読み書きします。このとき、0≦index<位置となります。

相対get/put

以下のように値が格納されたバッファに対して

    位置  リミット 容量    位置=2, リミット=6, 容量=9
     V       V     V
+-+-+-+-+-+-+-+-+-+-+
| | | | | | | | | | |
+-+-+-+-+-+-+-+-+-+-+
 0 1 2 3 4 5 6 7 8 9 

相対get/putで1項目を読み書きすると、位置が1つ進みます。

    位置  リミット 容量   位置=3, リミット=6, 容量=9
       V     V     V
+-+-+-+-+-+-+-+-+-+-+
| | | | | | | | | | |
+-+-+-+-+-+-+-+-+-+-+
 0 1 2 3 4 5 6 7 8 9 

位置やリミットを変更するメソッド

reset

位置をマークにセット、マークがなければInvalidMarkException例外

mark

現在の位置にマークをセット

clear

リミットを容量にセット、位置を0にセット

flip

    位置  リミット 容量   位置=3, リミット=6, 容量=9
       V     V     V
+-+-+-+-+-+-+-+-+-+-+
| | | | | | | | | | |
+-+-+-+-+-+-+-+-+-+-+
 0 1 2 3 4 5 6 7 8 9 

    ↓ flip

位置  リミット   容量     位置=0, リミット=3, 容量=9
 V     V           V
+-+-+-+-+-+-+-+-+-+-+
| | | | | | | | | | |
+-+-+-+-+-+-+-+-+-+-+
 0 1 2 3 4 5 6 7 8 9 

rewind

位置をゼロ

compact

    位置  リミット 容量   位置=3, リミット=6, 容量=9
       V     V     V
+-+-+-+-+-+-+-+-+-+-+
| | | |*|*|*| | | | |
+-+-+-+-+-+-+-+-+-+-+
 0 1 2 3 4 5 6 7 8 9 

    ↓ compact

    位置        リミット
                 容量     位置=3, リミット=9, 容量=9
       V           V
+-+-+-+-+-+-+-+-+-+-+
|*|*|*| | | | | | | |
+-+-+-+-+-+-+-+-+-+-+
 0 1 2 3 4 5 6 7 8 9 

イテレートする

バッファ内のバイトデータ列を、空白区切りで文字列にする

ByteBuffer buf = ...
while (buf.hasRemaining()) {
    System.out.print("%02x ", buf.get());
}

バッファ内のバイトデータ列を文字列化する

文字列が格納されたByteBufferから、文字列を取り出す。

ByteBuffer buf = ...
String text = StandardCharsets.UTF_8.decode(buf).toString();

いろいろ

動作例その1

  • buf = ByteBuffer.allocate(4);
位置     リミット
         容量       位置=0, リミット=4, 容量=4
 V       V
+-+-+-+-+
| | | | |
+-+-+-+-+
 0 1 2 3 4 
  • buf.put(d);
  位置   リミット
         容量       位置=1, リミット=4, 容量=4
   V     V
+-+-+-+-+
|*| | | |
+-+-+-+-+
 0 1 2 3 4 
  • buf.put(d)
   位置  リミット
         容量       位置=2, リミット=4, 容量=4
     V    V
+-+-+-+-+
|*|*| | |
+-+-+-+-+
 0 1 2 3 4 
  • buf.put(d)
   位置  リミット
         容量       位置=3 リミット=4, 容量=4
       V  V
+-+-+-+-+
|*|*|*| |
+-+-+-+-+
 0 1 2 3 4 
  • buf.put(d)
         位置
         リミット
         容量       位置=4, リミット=4, 容量=4
          V
+-+-+-+-+
|*|*|*|*|
+-+-+-+-+
 0 1 2 3 4 
  • buf.put(d)
    |  例外java.nio.BufferOverflowException
    |        at Buffer.nextPutIndex (Buffer.java:662)
    |        at HeapByteBuffer.put (HeapByteBuffer.java:196)
    |        at (#28:1)
    


ほぼ3年前に更新