1

使用 OkHttp Websocket 时,侦听器使用 ByteString 向应用程序提供二进制有效负载。我想将这些字节输入到一些采用 okio.Source(在本例中为 GzipSource)的代码中,但我找不到任何有效地执行此操作的好方法。

我目前的解决方案如下所示:

        @Override
        public void onMessage(WebSocket webSocket, ByteString bytes) {
            Buffer gzipBuffer = new Buffer();
            gzipBuffer.write(bytes);

            GzipSource gzipSource = new GzipSource(gzipBuffer);
            ....
        }

这样做的缺点Buffer.write是它会产生额外的字节副本(在 Buffer 的情况下,是分段的,即使池化也是额外的开销)。WebSocketReader在这个 Websocket 案例中,一个字节数组只是为 ByteString 本身分配的(当从impl移交时)。

我的问题是:有没有其他首选的方式来读取 a ByteString,通过 a Source?由于ByteString应该是不可变的并且 aSource只会保存一些读取位置信息,我认为它应该是完全可行的(但不是来自外部代码,因为我无法访问byte[]).. 所以感觉就像我错过了这里有明显的解决方案.. :)

感谢您的任何提示或指示!

4

1 回答 1

1

您编写它的方式几乎是最佳的。

Okio 已针对在转换层之间移动数据进行了优化:压缩、成帧、线程等。虽然在层之间移动数据非常快(无副本),但最初将数据导入系统是有前期成本的。这通常是您无论如何都需要做的 I/O:加载文件或发送数据包。但在这种情况下,您必须复制才能将字节放入第一个缓冲区。这感觉效率低下,但好处是你的下一个 Source.read() 调用会很快,所以整体效果仍然很好。

于 2019-02-06T01:12:27.743 回答