【问题标题】:Best practice to read limited length from an input stream从输入流中读取有限长度的最佳实践
【发布时间】:2013-11-18 01:52:33
【问题描述】:

我有通过套接字发送的数据包,这些数据包前面是长度标头。因此,每次传输都带有 4 个字节的长度信息,然后是数据包。因此,我必须限制我的read() 永远不会超过长度,这样我就不会意外读取行中的下一个数据包。

InputStream in 是输入流,ByteArrayOutputStream byteStream 是我将传入数据包写入的流,int len 是传入传输的长度。

这是我想出的:

for (int i = 0; i < len; i++) {
    byteStream.write(in.read());
}

这绝对是可怕的;逐个读取字节。我希望看看是否有更好的方法来使用缓冲区(有点类似于复制流的规范方式)。

【问题讨论】:

  • 根据您的要求将字节数读入数组。如果您知道数据包的最大长度,它会变得更容易,因为您只需要声明一次数组,否则您需要为每个数据包创建一个新数组,看看InputStream#read(byte[], int, int)

标签: java java-8 java-stream


【解决方案1】:

将输入流包装在 DataInputStream 中,然后使用 readInt() 和 readFully() 方法获取数据的大小和字节数。

int len = dis.readInt();
// assuming relatively small byte arrays, use smarter logic for huge streams....
byte[] buffer = new byte[len];
dis.readFully(buffer);
byteStream.write(buffer);

【讨论】:

  • 现在包含示例。
  • 啊,对,我以为你不能在运行时声明可变数组大小(C89 在我脑海中留下的东西)。
  • 重新阅读我的答案我可以理解为什么我写的内容没有描述我认为我在说什么......将编辑。
  • new byte[len] 在性能方面不会成为问题吗?如果len 很大,分配数组时可能会产生问题,不是吗?
  • 是的,它可能是,所以,更聪明的做法是构建和重用一个较小的缓冲区,然后根据需要多次使用 readFully(byte[], 0, partlen); 变体循环输入,其中partlen 是完整的缓冲区大小,除了最后一次循环。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-05
  • 1970-01-01
  • 2016-03-04
  • 2018-05-25
  • 1970-01-01
相关资源
最近更新 更多