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

dul*_*shi 7 java protocol-buffers

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

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

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

Ken*_*rda 6

你不能byte[]ByteString不复制的情况下从 a获取 a ,因为这将允许你修改 的内容ByteString,这意味着ByteString不能再保证它是不可变的。这很像为什么你不能char[]String没有复制的情况下从 a 中获得 a ,即使String它实际上是由幕后支持的char[]。这可能是一个安全问题:在安全域之间传递StringByteString在安全域之间传递时,重要的是接收方可以知道发送方在使用字符串时不会从它们下面修改字符串。

但是,您可以在没有副本的情况下调用asReadOnlyByteBufferList()get 来ByteBuffer表示底层数据,因为它ByteBuffer强制执行不变性。


Vla*_*nev 5

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

但是很可能toByteArray()很快就会满足您的需求System.arraycopy()

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


小智 5

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