android – Protobuf流(懒惰序列化)API

android – Protobuf流(懒惰序列化)API,第1张

概述我们有一个 Android应用程序,它使用Protocol Buffers来存储应用程序数据.数据格式(粗略地)是单个protobuf(“容器”),其包含作为重复字段的protobufs(“items”)列表: message Container { repeated Item item = 1;} 当我们想要保存对项目的更改时,我们必须重新创建protobuf容器,将所有项目添加到其中 我们有一个 Android应用程序,它使用Protocol Buffers来存储应用程序数据.数据格式(粗略地)是单个protobuf(“容器”),其包含作为重复字段的protobufs(“items”)列表:

message Container {    repeated Item item = 1;}

当我们想要保存对项目的更改时,我们必须重新创建protobuf容器,将所有项目添加到其中,然后将其序列化并将其写入文件.

这种方法的问题是它可能使保存时使用的内存增加三倍,因为数据必须首先从模型类复制到protobuf构建器,然后在protobuf序列化时复制到字节数组,所有这些都在写入之前文件流.

我们想要的是一种创建我们的protobuf容器并懒惰地将其序列化为流的方法,然后简单地将每个protobuf项(从我们的模型数据创建)添加到容器中,该容器将其序列化并将其写入流,而不是保留所有内存中的项目,直到我们在内存中创建了整个容器.

有没有办法构建一个protobuf并将其懒洋洋地序列化为流?

如果没有办法正式执行此 *** 作,是否有任何库可以提供帮助?有没有人有任何建议或想法如何以其他方式解决这个问题?替代数据格式或技术(例如JsON或包含protobufs的XML)可以实现这一目标吗?

解决方法 对于序列化:

protobuf是一种可附加格式,其中合并了各个项目,并附加了重复的项目

因此,要将序列编写为惰性流,您需要做的就是重复编写相同的结构,列表中只有一个项目:序列化200 x“Container with 1 Item”的序列与序列化1 x 100%相同“有200个项目的容器”.

所以:就这样做!

对于反序列化:

从技术上讲,这很容易被视为一个流 – 然而,这一切都归结为您正在使用的库.例如,我在protobuf-net(一个.NET / C#实现)中将它暴露为Serializer.DeserializeItems< T>,它基于它们所处的假设读取(完全延迟/流式传输)T类型的消息序列.您在问题中描述的表单(因此Serializer.DeserializeItems< Item>将是替换Serializer.Deserialize< Container>的流式方式 – 最外层的对象有点并不存在于protobuf中)

如果这不可用,但您可以访问原始阅读器API,那么您需要做的是:

>为标题读取一个varint – 这将是值10(0x0A),即分别为字段编号(1)和线型(2)的“(1 << 3)| 2” - 所以这也可以措辞:“从流中读取一个字节,并检查值是10”
>读取一个varint以获取以下项目的长度
>现在:

>如果reader API允许您限制要处理的最大字节数,请使用此长度指定后面的长度
>或使用长度限制流包装流API,限制为该长度
>或者只是手动读取那么多字节,并从有效负载构造内存中的流

>冲洗,重复

总结

以上是内存溢出为你收集整理的android – Protobuf流(懒惰序列化)API全部内容,希望文章能够帮你解决android – Protobuf流(懒惰序列化)API所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1127279.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-30
下一篇 2022-05-30

发表评论

登录后才能评论

评论列表(0条)

保存