【问题标题】:Java Why does the constructor for a DatagramPacket need the length of the byte array?Java 为什么 DatagramPacket 的构造函数需要字节数组的长度?
【发布时间】:2019-12-16 11:29:32
【问题描述】:

根据 javadocs,DatagramPacket 类中的构造函数需要一个字节数组和一个小于或等于该数组长度的整数。 例如:

DatagramPacket(byte[] buf, int length)

我看到的所有例子都只是像这样传递字节数组的长度属性:

byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);

对于这个(常见的)用例,在构造函数中访问传递的字节数组的长度属性会更简单。为什么所有构造函数都明确需要长度参数?

【问题讨论】:

  • 如果要使用的长度小于数组长度。
  • 也许用户希望重用一个缓冲区对象,即使缓冲区的长度可能会改变。想象一下发送一个缓冲区长度为 1,000 的文件。几乎可以肯定的是,最后发送的数据包长度小于 1,000。

标签: java udp datagram


【解决方案1】:

“为什么”这个问题的准确答案就是“因为”。规范是这样说的,请注意DatagramPacket 从一开始就是 java 的一部分(好吧,我猜是在橡树之后):javadoc 被标记为@since 1.0

我们所能做的就是猜测这个 API 的原始开发者的想法。

所以我会尝试这样做:

  1. 此 API 早于提供(dataStore)(dataStore, offset, length) 变体(并且没有其他变体)的约定。例如,在new String(byteArray, offset, length, charset) 构造函数中,以及几乎所有其他出现这种概念的地方,您必须在传递整个数据存储区或同时传递偏移量和长度之间做出选择;你永远不能只传递长度并且偏移量默认为0。但你可以在这里;那是因为还没有这个约定。

  2. 之所以存在“传递偏移量和长度”的概念,不仅在这里,而且还有基于字符串的基于字节数组的构造函数,OutputStream 的 write 方法同时出现在 write(byte[] data)以及write(byte[] data, int offset, int length) 变体,以及 java 核心库中的许多、许多 其他地方,是因为您的缓冲区通常比您拥有的数据量大。如果您还不知道要在数据报包中发送多少数据,您可以将所有数据生成一个自增长的结构,例如 ByteArrayOutputStreamStringBuilderArrayList<Byte>,写取出所有数据,然后从中提取适当大小的byte[] 数组。或者,这是 VASTLY 更有效率,你制作一个绝对足够大的字节数组来存储你要制作的任何东西,如果必须的话,可以选择使用 ThreadLocal 重用它,一旦你'完成了,只有现在你才知道它实际上必须有多大。而不是制作另一个大小合适的字节数组并复制所有字节,只需..发送“缓冲区数组”的前 X 个字节,为自己节省内存和复制操作。同样也有不希望从 0 开始的原因。这就是为什么DatagramPacket 也有(byte[] buf, int offset, int length) 构造函数的原因,这也解释了为什么字节数组的参数名称实际上是buf(缓冲区的缩写,注意它不是更明显的名称@987654337 @)。

  3. ByteBuffer 是一个专门为做好这一点而设计的概念。我不确定为什么DatagramPacket 中仍然没有构造函数来处理这些,但数据报包本身比字节缓冲区早了十年或更长时间。如果 bytebuffers 从 1.0 开始成为语言的一部分,这可能已经使用 bytebuffers 完成,它完全代表了具有固定大小缓冲区的概念,并且对于使用可能未知长度的数据进行写入/读取的代码非常有效它恰好在正确的位置,并且不超过某个限制,以避免不得不在整个地方制作字节数组。

【讨论】:

  • 或者仅仅因为它与InputStream.read(byte[]) 配合得很好。您从输入流中读取块,并使用来自read(buf) 的返回值作为长度发送每个块。合同不保证整个缓冲区都被填满,最后一个数据包几乎总是小于那个缓冲区。它使循环易于阅读。
  • (1) 不正确。此 API 与输入和输出流等中的所有 (byte[], offset, length) 参数列表一起出现在 Java 1.0 中。没有先行者。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-06-04
  • 1970-01-01
  • 2020-03-10
  • 1970-01-01
  • 1970-01-01
  • 2011-02-25
相关资源
最近更新 更多