3

このコードスニペットを理解しようとしています

        DataInputStream stream = 
          new DataInputStream(
            new ByteArrayInputStream(messageBuffer));


        int     messageLength   = stream.readInt();
        char    recordType      = (char) stream.readByte();
        byte    padding         = stream.readByte();
        short   numberRecords   = stream.readShort();

messageBufferは、Socket.read()メソッドを介して入力される新しいバイト[32768]として初期化されます。私が理解していないのは、messageLengthがstream.readInt()に初期化されると、2番目の2番目のステートメント、つまりrecordTypeはどのように機能するのでしょうか。

最初のステートメントはバイト配列の先頭からintを読み取り、次のステートメントはバイト配列の先頭からバイトを読み取りませんか?どのポイントからバイト、int、shortなどを読み取るかをどの程度正確に知ることができますか?

4

4 に答える 4

5

ドキュメントから:

AByteArrayInputStreamには、ストリームから読み取ることができるバイトを含む内部バッファが含まれています。内部カウンターは、メソッドによって提供される次のバイトを追跡します。read

言い換えると、DataInputStream単にから読み取りますがByteArrayInputStream、後者はバイト配列内の現在の位置を記憶し、データが読み取られるたびにそれを進めます。

于 2011-08-03T13:02:35.917 に答える
3

DataInputStream.read*メソッドは、基になる入力ストリームからバイトを消費します。この場合、read*メソッドは、によって提供される次に使用可能なバイトを読み取りByteArrayInputStream、配列内の現在の位置を追跡します。


補足として、ByteBuffer.wrapさまざまなByteBuffer.read方法の使用を検討することをお勧めします。

ByteBuffer msgBuf = ByteBuffer.wrap(messageBuffer);
int messageLength = msgBuf.getInt();
char recordType   = msgBuf.getChar();
...
于 2011-08-03T13:04:01.017 に答える
3

readX()ストリームの先頭から読み取りません。実際、ストリームという用語は、時間の経過とともに利用可能になる一連のデータを表すために使用されます。つまり、ストリームからの後続の読み取りでは、さまざまな要素が取得されます。

ストリームは、配列ではなく、情報のコンベヤー ベルトと考えてください。

于 2011-08-03T13:05:23.597 に答える
1

Socket.read() は、利用可能なバイトを読み取ります。最小は 1 バイトです。最大値は、任意の数のメッセージを格納できるバッファー サイズです。

バッファーを手動で読み取る代わりに、DataInputStream/BufferedInputStream を使用する方が安全で、簡単で、効率的です。

// create an input stream once per socket.
DataInputStream stream = 
      new DataInputStream(
        new BufferedInputStream(socket.getInputStream()));


int     messageLength   = stream.readInt();
char    recordType      = (char) stream.readByte();
byte    padding         = stream.readByte();
short   numberRecords   = stream.readShort();
于 2011-08-03T13:34:15.870 に答える