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 被初始化为 new byte[32768],通过 Socket.read() 方法填充。我不明白的是,一旦 messageLength 被初始化为 stream.readInt(),第二个语句将如何工作,即 recordType?

第一条语句不会从字节数组的开头读取一个 int,而下一条语句会从字节数组的开头读取一个字节吗?它如何确切地知道从哪个点读取字节、整数、短裤等?

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() 将读取可用的字节。最小值是一个字节!最大值是缓冲区大小,其中可以包含任意数量的消息。

与手动读取缓冲区不同,使用 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 回答