JAVA NIOでのByteBuffer
3028 ワード
ByteBufferには主に以下の属性があります.
capacity
最大格納可能なByte数を示す容量サイズ
position
操作ポインタは、getやputを次回呼び出すとここから読み出され、言い換えればput/getごとにpositionが1回増加します.
limit
キャッシュ領域の「有効」を表す要素の長さ、例えばByteBufferの容量capacityが10に設定されている場合、この10バイトはデフォルトで0(数値なしを示す)であり、limitの役割は10バイトのうち何バイトが有効かを示す.buffer putに5バイト入るとlimitは5.
ByteBufferの主な方法
clear()--主に書き込みの準備をする前に呼び出すために使用されます.
Bufferの中のデータをクリアして、すべてのバイトをクリアして、limitを0に設定して、positionを0に設定して毎回bufferをいっぱい読むようにして、次を読む前にゼロにするべきで、bufferがいっぱいになったために読み続けることができません.ソース:
flip()--主にputメソッドを呼び出してデータを書き終わった後に読み出す準備(getメソッドを呼び出す)に使用されます.
現在のposition位置を記録し(limitを変更して現在の有効バイト位置を記録する)、positionを0にクリアします.ソース:
reset()--主にbufferをループして読み込むためのデータ使用
現在のpositionポインタを、mark()メソッドが最後に呼び出されて記録された場所に移動します.たとえば、同じメッセージを異なるクライアントソースコードにブロードキャストします.
mark()--主にresetを準備する前に使用します.
現在のposition位置を記録し、次のresetを待つときにソースコードを使用します.
bufferにputが1回データを完了すると、positionとlimitは同時に増加し、基本的に同期し、putが10バイトになった場合、positionとlimitは0から10に増加します.一方、positionは前述したようにgetやputの操作に用いられ、bufferへのputが完了した後、positionの設定を行わずに直接getを行うと、当然データは読み込めません.
remaining()
クエリーに現在どれだけの「有効」データが使用可能か、すなわちpositionとlimitの差を判断します.
サンプルコード:
コンソールの入力内容をループしてsocketに書き込む
初歩的に理解するために、このコードは基本的な使い方を簡単に示すだけで、実際にはbytesがbufferより大きい場合を考慮して、次のコードに変更します.
capacity
最大格納可能なByte数を示す容量サイズ
position
操作ポインタは、getやputを次回呼び出すとここから読み出され、言い換えればput/getごとにpositionが1回増加します.
limit
キャッシュ領域の「有効」を表す要素の長さ、例えばByteBufferの容量capacityが10に設定されている場合、この10バイトはデフォルトで0(数値なしを示す)であり、limitの役割は10バイトのうち何バイトが有効かを示す.buffer putに5バイト入るとlimitは5.
ByteBufferの主な方法
clear()--主に書き込みの準備をする前に呼び出すために使用されます.
Bufferの中のデータをクリアして、すべてのバイトをクリアして、limitを0に設定して、positionを0に設定して毎回bufferをいっぱい読むようにして、次を読む前にゼロにするべきで、bufferがいっぱいになったために読み続けることができません.ソース:
public final Buffer clear() {
position = 0;
limit = capacity;
mark = -1;
return this;
}
flip()--主にputメソッドを呼び出してデータを書き終わった後に読み出す準備(getメソッドを呼び出す)に使用されます.
現在のposition位置を記録し(limitを変更して現在の有効バイト位置を記録する)、positionを0にクリアします.ソース:
public final Buffer flip() {
limit = position;
position = 0;
mark = -1;
return this;
}
reset()--主にbufferをループして読み込むためのデータ使用
現在のpositionポインタを、mark()メソッドが最後に呼び出されて記録された場所に移動します.たとえば、同じメッセージを異なるクライアントソースコードにブロードキャストします.
public final Buffer reset() {
int m = mark;
if (m < 0)
throw new InvalidMarkException();
position = m;
return this;
}
mark()--主にresetを準備する前に使用します.
現在のposition位置を記録し、次のresetを待つときにソースコードを使用します.
public final Buffer mark() {
mark = position;
return this;
}
bufferにputが1回データを完了すると、positionとlimitは同時に増加し、基本的に同期し、putが10バイトになった場合、positionとlimitは0から10に増加します.一方、positionは前述したようにgetやputの操作に用いられ、bufferへのputが完了した後、positionの設定を行わずに直接getを行うと、当然データは読み込めません.
remaining()
クエリーに現在どれだけの「有効」データが使用可能か、すなわちpositionとlimitの差を判断します.
サンプルコード:
コンソールの入力内容をループしてsocketに書き込む
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
ByteBuffer buffer = ByteBuffer.allocate(1024);
while (true) {
try {
String s = reader.readLine();
byte[] bytes = s.getBytes(utf8);
buffer.clear();// buffer
buffer.put(bytes);
buffer.flip();// buffer , position
socketChannel.write(buffer);
} catch (IOException e) {
e.printStackTrace();
}
}
初歩的に理解するために、このコードは基本的な使い方を簡単に示すだけで、実際にはbytesがbufferより大きい場合を考慮して、次のコードに変更します.
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
ByteBuffer buffer = ByteBuffer.allocate(1024);
while (true) {
try {
String s = reader.readLine();
byte[] bytes = s.getBytes(utf8);
buffer.clear();
for (int offset = 0; offset < bytes.length; offset++) {
buffer.put(bytes[offset]);
if (buffer.remaining() == 0) {
buffer.flip();
socketChannel.write(buffer);
buffer.clear();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}