协议缓冲区:从字节字符串获取字节数组,无需复制

2022-09-04 21:22:04

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

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

是否有任何API可以做到这一点,或者性能损失是可以接受的?


答案 1

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

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

如果您确实由于长数组复制而遇到性能问题,并且您不想直接传递,请查看 和 方法。它们将内容包装进去而不复制它们。ByteStringasReadOnlyByteBuffer()asReadOnlyByteBufferList()ByteStringByteBuffer


答案 2

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

但是,您可以调用来获取表示基础数据的 s,而无需复制,因为强制实施不可变性。asReadOnlyByteBufferList()ByteBufferByteBuffer


推荐