协议缓冲区:从ByteString获取字节数组而不进行复制

时间:2015-05-29 08:15:39

标签: java protocol-buffers

假设我有一个方法void foo(byte[] bytes)需要一个字节数组作为参数。 Howerver,Protobuf中字节数组的Java类型是ByteString

我可以使用byte[] toByteArray()来获取字节数组。但问题是这个方法使用副本构建一个新的数组,这是相对昂贵的。我宁愿它直接返回底层数组,或者返回一个视图。

是否有任何API,或性能损失是否可以接受?

3 个答案:

答案 0 :(得分:5)

通常这是不可能的,因为ByteString的某些子类中可能没有这样的数组。 BoundedByteString可以包含更大的数组,因此需要复制才能获得正确大小的数组。 RopeByteString由其他字节字符串组成,因此需要复制才能将内容放入一个数组中。 LiteralByteString将内容存储在正确大小的数组中,但它不提供直接访问它的方法。

但最有可能toByteArray()足以满足您的需求,因为System.arraycopy()非常快。

如果由于长阵列复制确实存在性能问题,并且您不想直接传递ByteString,请查看asReadOnlyByteBuffer()asReadOnlyByteBufferList()方法。他们将ByteString内容包装到ByteBuffer而不复制它们。

答案 1 :(得分:3)

如果没有复制,您无法从byte[]获得ByteString,因为这样您就可以修改ByteString的内容,这意味着ByteString无法保证这是不可改变的。这就像为什么你无法在没有复制的情况下从char[]获得String的原因,即使String实际上由char[]支持。这可能是一个安全问题:在安全域之间传递StringByteString时,接收方可以知道发件人在使用它时不会从其下面修改字符串,这一点很重要。

但是,您可以调用asReadOnlyByteBufferList()来获取代表基础数据的ByteBuffer而无需副本,因为ByteBuffer强制执行不变性。

答案 2 :(得分:-1)

com.google.protobuf.UnsafeByteOperations.unsafeWrap(byte[], int, int)