假设我有一个方法void foo(byte[] bytes)
需要一个字节数组作为参数。 Howerver,Protobuf中字节数组的Java类型是ByteString
。
我可以使用byte[] toByteArray()
来获取字节数组。但问题是这个方法使用副本构建一个新的数组,这是相对昂贵的。我宁愿它直接返回底层数组,或者返回一个视图。
是否有任何API,或性能损失是否可以接受?
答案 0 :(得分:5)
通常这是不可能的,因为ByteString
的某些子类中可能没有这样的数组。 BoundedByteString
可以包含更大的数组,因此需要复制才能获得正确大小的数组。 RopeByteString
由其他字节字符串组成,因此需要复制才能将内容放入一个数组中。 LiteralByteString
将内容存储在正确大小的数组中,但它不提供直接访问它的方法。
但最有可能toByteArray()
足以满足您的需求,因为System.arraycopy()
非常快。
如果由于长阵列复制确实存在性能问题,并且您不想直接传递ByteString
,请查看asReadOnlyByteBuffer()
和asReadOnlyByteBufferList()
方法。他们将ByteString
内容包装到ByteBuffer
而不复制它们。
答案 1 :(得分:3)
如果没有复制,您无法从byte[]
获得ByteString
,因为这样您就可以修改ByteString
的内容,这意味着ByteString
无法保证这是不可改变的。这就像为什么你无法在没有复制的情况下从char[]
获得String
的原因,即使String
实际上由char[]
支持。这可能是一个安全问题:在安全域之间传递String
或ByteString
时,接收方可以知道发件人在使用它时不会从其下面修改字符串,这一点很重要。
但是,您可以调用asReadOnlyByteBufferList()
来获取代表基础数据的ByteBuffer
而无需副本,因为ByteBuffer
强制执行不变性。
答案 2 :(得分:-1)
见com.google.protobuf.UnsafeByteOperations.unsafeWrap(byte[], int, int)