1

バイト配列があり (符号なしバイトはオプションではないため)、そのうちの 4 つを 32 ビット int に変換する必要があります。私はこれを使用しています:

byte rdbuf[] = new byte[fileLen+1];
int i = (rdbuf[i++]) | ((rdbuf[i++]<<8)&0xff00) | ((rdbuf[i++]<<16)&0xff0000) | ((rdbuf[i++]<<24)&0xff000000);

すべての論理ANDを実行しないと、バイトが符号拡張されますが、これは明らかに私が望んでいるものではありません。

cでは、これは簡単なことではありません。Javaでより良い方法はありますか?

4

2 に答える 2

11

これを行う必要はありません。次を使用できますByteBuffer

int i = ByteBuffer.wrap(rdbuf).order(ByteOrder.LITTLE_ENDIAN).getInt();

読み取る int が多数ある場合、コードは次のようになります。

ByteBuffer buf = ByteBuffer.wrap(rdbuf).order(ByteOrder.LITTLE_ENDIAN);

while (buf.remaining() >= 4) // at least four bytes
    i = bb.getInt();

ここにJavadocがあります。バイナリ データを処理する必要があるあらゆる状況での使用をお勧めします (そのようなデータの読み取りまたは書き込みに関係なく)。リトル エンディアン、ビッグ エンディアン、さらにはネイティブの順序付けを行うことができます。(注: デフォルトではビッグエンディアン)。

(編集: @PeterLawrey は、これがリトル エンディアン データ、固定コード抽出のように見えることを正しく述べています。また、ファイルの内容を に直接ラップする方法については、彼の回答を参照してくださいByteBuffer)

ノート:

  • ByteOrderと呼ばれる静的メソッドが.nativeOrder()あり、基礎となるアーキテクチャで使用されるバイト順を返します。
  • aByteBufferにはオフセットが組み込まれています。現在のオフセットは、 を使用して照会したり、 を使用.position()して変更したりできます.position(int).remaining()現在のオフセットから最後まで読み取るために残っているバイト数を返します。
  • バッファーの現在のオフセットで読み取り/書き込みを行う相対メソッドと、指定したオフセットで読み取り/書き込みを行う絶対メソッドがあります。
于 2013-01-14T13:09:25.730 に答える
1

シフト/マスクを行う ByteBuffer でラップする必要がある byte[] に読み込む代わりに、このオーバーヘッドをすべて回避する直接 ByteBuffer を使用できます。

FileChannel fc = new FileInputStream(filename).getChannel();
ByteBuffer bb = ByteBuffer.allocateDirect(fc.size()).order(ByteBuffer.nativeOrder());
fc.read(bb);
bb.flip();
while(bb.remaining() > 0) {
    int n = bb.getInt(); // grab 32-bit from direct memory without shift/mask etc.
    short s = bb.getShort(); // grab 16-bit from direct memory without shift/mask etc.

    // get a String with an unsigned 16 bit length followed by ISO-8859-1 encoding.
    int len = bb.getShort() & 0xFFFF;
    StringBuilder sb = new StringBuilder(len);
    for(int i=0;i<len;i++) sb.append((char) (bb.get() & 0xFF));
    String text = sb.toString(); 
}
fc.close();
于 2013-01-14T13:19:55.797 に答える