java.nio.BufferUnderflowException分析


詳細
簡単なBufferの小さな例を書くとき、異常を投げ出します.
Exception in thread "main" java.nio.BufferUnderflowException
	at java.nio.Buffer.nextGetIndex(Buffer.java:498)
	at java.nio.HeapByteBuffer.getChar(HeapByteBuffer.java:253)
	at com.malone.nio.BufferDemo.main(BufferDemo.java:22)

例のコードは次のとおりです.
public class BufferDemo {

	public static void main(String[] args) throws IOException {
		RandomAccessFile  file = new RandomAccessFile ("D:\\https.txt", "rw");
		FileChannel fc = file.getChannel();
		ByteBuffer b = ByteBuffer.allocate(64);
		while (true) {
			int readFlag = fc.read(b);
			if (readFlag == -1) {
				break;
			}
			b.flip();
			while (b.hasRemaining()) {
				
			    System.out.println(b.getChar() + "    " + b.position() +  "   " + b.remaining());
                        }
			b.clear();
		}
		file.close();
	}
}

異常位置決めにより、Bufferの内容を印刷中にエラーを報告した場合、よく分析して、エラーの原因を推測します.
getChar()メソッドを呼び出します.charの文字長が2バイトで、ByteBufferのremaining長が1の場合、強引に2バイトを取得すると例外が放出されるはずです
 
以上の考え方に基づいて、例コードを修正し、印刷コードを以下に変更します.
System.out.println(b.getChar() + "    " + b.position() +  "   " + b.remaining());

コンソールの印刷構造は次のとおりです.
쳡    44   20
쪾    46   18
ꎬ    48   16
듋    50   14
솴    52   12
뷓    54   10
늻    56   8
뿉    58   6
탅    60   4
죎    62   2
ꎬ    64   0
퓲    2   19
엤    4   17
훃    6   15
     8   13
     10   11
     12   9
랾    14   7
뎳    16   5
즹    18   3
ꚣ    20   1
Exception in thread "main" java.nio.BufferUnderflowException
	at java.nio.Buffer.nextGetIndex(Buffer.java:498)
	at java.nio.HeapByteBuffer.getChar(HeapByteBuffer.java:253)
	at com.malone.nio.BufferDemo.main(BufferDemo.java:22)

コンソール印刷の結果、ByteBufferの配列から2バイトずつ取り出して印刷し、positionの値を移動し、最後に移動するとpositionとlimitの間に1バイトしかない場合、2バイトを取得しようとすると異常が放出されることがわかります!
 
ByteBufferの内容を印刷するときに、ByteBufferのget()メソッドを使用すると、上記の問題は発生せず、get()メソッドは1バイトずつ取得されます