androidはjavaを解決します.nio.BufferOverflowException異常


昨日、プログラムをテストしたとき、javaを見つけました.nio.BufferOverflowExceptionは異常で、その後、ネットで資料を検索して、やっと問題を解決しました.ここに記録しておきます.
ByteBuffer params = ByteBuffer.allocate(2);//         2   ,   params.put(tmp); put 3      。     java.nio.BufferOverflowException   
        params.order(ByteOrder.LITTLE_ENDIAN); 
         
         byte[] tmp = new byte[3];
         tmp[0] = (byte) data1;
         tmp[1] = (byte) data2;
         tmp[2] = (byte) data3;


       params.put(tmp);

エラーの原因:書き込みの長さが許容される長さを超えています.
どうやってこの問題を解決しますか?
書き込み長とByteBufferで書き込み可能な長さの判断を追加します.たとえば、次のようにします.
		while (writeBuffer.remaining() > 0) {
			writeBuffer.put((byte)0);
		}

注意:毎回1バイトしか書き込まない場合は、0より大きいと判断すればいいのですが、条件の変更を覚えていない場合は!
まとめ
ByteBufferremaining()が読み取りまたは書き込みの長さより小さい場合、読み取りまたは書き込み操作を実行しても異常が発生します.
読み込みはjavaを生成する.nio.BufferUnderflowException異常
書き込みはjavaを生成する.nio.BufferOverflowException異常.
ByteBufferremaining()が0に等しい場合、読み取りや書き込みは実行できません.clear()操作を実行する必要があります.そうしないと異常が発生します.
ここではBufferの関数をいくつか紹介します
1、アクセス(Buffer.get()&Buffer.put())
get()を使用してバッファからデータを取り出し、put()を使用してバッファにデータを格納します.
		//        10 byte     
		ByteBuffer buff = ByteBuffer.allocate(10);
		//   4   
		buff.put((byte) 'A');
		buff.put((byte) 'B');
		buff.put((byte) 'C');
		buff.put((byte) 'D');
		//      
		buff.flip();
		//   2   
		System.out.println((char)buff.get());
		System.out.println((char)buff.get());

バッファの4つの属性値は必ずcapacity>=limit>=position>=mark>=0に従い、put()の場合、positionがlimitを超えるとBufferOverflowExceptionが投げ出されます.get()の場合、positionがlimitを超えるとBufferUnderflowExceptionが放出されます.
        buff.flip()はバッファを反転し、反転は以下のようになります.
put()またはget()を呼び出すと、positionの値が呼び出されるたびに1が加算され、次回の保存または取得の開始位置を示す.
さらにBufferにデータを読み書きする際にも2つの方法があります.
Buffer.remaining():現在の位置から上界までのデータ要素の数を返します.
Buffer.hasRemaining():現在の位置から上界にデータ要素があるかどうかを教えてくれます.
2、反転(Buffer.flip()
反転とは、データが格納されているバッファをデータを取得する準備ができている状態にし、flip()方式で反転を実現することである.Buffer.flip()のソースコードは次のとおりです.
	public final Buffer flip() {
		limit = position;
		position = 0;
		mark = -1;
		return this;
	}

実装されたソースコードを見るとflip()の役割がわかると信じています.rewind()の方法はflip()とよく似ているが、rewind()はlimitに影響を及ぼさず、flip()はlimit属性値、Bufferをリセットする.rewind()のソースコードは次のとおりです.
	public final Buffer rewind() {
		position = 0;
		mark = -1;
		return this;
	}

3、圧縮(Buffer.compact()
圧縮とは、読み取ったデータを破棄し、読み取っていないデータを保持し、保持したデータをバッファの上部に再充填し、バッファにデータを書き込み続けることです.
		//        10 byte     
		ByteBuffer buff = ByteBuffer.allocate(10);
		//      
		buff.put((byte)'A');
		buff.put((byte)'B');
		buff.put((byte)'C');
		buff.put((byte)'D');
		System.out.println("first put : " + new String(buff.array()));
		//  
		buff.flip();
		//  
		System.out.println((char)buff.get());
		System.out.println((char)buff.get());
		//  
		buff.compact();
		System.out.println("compact after get : " + new String(buff.array()));
		//    
		buff.put((byte)'E');
		buff.put((byte)'F');
		//    
		System.out.println("put after compact : " + new String(buff.array()));

以上のコードの印刷結果:
first put : ABCD
A
B
compact after get : CDCD
put after compact : CDEF
コンソールの出力内容に正方形の文字化けしがあり、正常です.バイトバッファに値が割り当てられていないメモリブロックのデフォルト値は0であり、Unicode符号化には0符号化がないため、文字化けしてしまう.
ここで簡単に説明します.
方法
説明
Limit()、limit(10)など
この4つの属性の読み取りと設定方法の名前はjQueryのval()と似ており、val(10)はgetを担当し、setを担当している.
reset()
positionをmarkの値に設定すると、前にマークをしたことに相当し、今は前のマークの場所に戻ります.
clear()
position = 0;limit = capacity;mark = -1; 少し初期化された味がしますが、下位byte配列の内容には影響しません.
flip()
limit = position;position = 0;mark = -1; フリップは、flipの後のpositionからlimitの領域を前の0からpositionの領域にし、フリップはデータが格納されているバッファをデータを取得する準備ができている状態にすることです.
rewind()
positionを0、markを-1に設定し、limitの値を変更しない
remaining()
return limit - position; 戻りlimitとpositionの相対位置差
hasRemaining()
return positioncompact()
positionからlimitの内容を0からlimit-positionの領域に移動し,positionとlimitの値もそれぞれlimit-position,capacityとなる.positonをlimitに設定してcompactするとclear()に相当します.
get()
相対的に読み、position位置からbyteを読み出し、position+1を次回の読み書きの準備にします.
get(int index)
絶対読み、byteBuffer下層のbytesにindexと下付きのbyteを読み、positionを変更しない
get(byte[] dst, int offset, int length)
position位置から相対的に読み、length個byteを読み、dst下付きoffsetからoffset+lengthまでの領域を書き込む
put(byte b)
相対的に書く、positionの位置にbyteを書き、postion+1を次回の読み書きの準備にする
put(int index, byte b)
絶対書き、byteBuffer下部のbytesにindexと下付きの位置にbyte bを挿入し、positionを変更しない
put(ByteBuffer src)
このbyteBufferには、srcの読み取り可能な部分(つまりpositionからlimit)を相対的に書きます.
put(byte[] src, int offset, int length)
src配列のoffsetからoffset+length領域にデータを読み込み、このbyteBufferに相対的に書き込む
byte配列を格納する必要がある場合、buffer.put(Byte[]b)とput(b,0,b.length)は同じです.
androidはjavaを解決します.nio.BufferOverflowException異常は終わりです.
簡単です.