Proto3序列化数到文件与反序列化
proto3序列化很好用,在原来开发APP存数据到日志时,日志文档半小时可达300M,数据量大时对性能有很大影响,因此改用proto序列化存储数据,经测试性能有所提升,日志大小为原来三分之一,所以优势还是很明显的。
但proto3序列化多条消息到文件时,按官方文档介绍,反序列化时是没法区分一个完整对象序列化数据的界限的,也就是没有分隔符,因此需要自己设定分隔符,反序列化时按规则解即可,以下是基于上一篇文章中环境的案例
一、多消息持续序列化规则
每个对象序列化后字节数的长度作为序列化内容前置4个字节的数据,即若一条序列化数据长度为100个字节,那么前这个数据前加4个字节,这4个字节的内容是100,那么总长度就是104个字节,依此规则持续序列化到文件即可
二、定义proto数据结构
syntax = "proto3"; package tutorial; message Person { string name = 1; int32 id = 2; string email = 3; string phone = 4; }
三、序列化测试
/** * 序列化 * * @param path */ private void serializeProto(String path) { System.out.println("serialize file " + path); try { OutputStream outputStream = new FileOutputStream(new File(path)); byte[] data; for (int i = 0; i < 10; i++) { Message.Person person = Message.Person.newBuilder().setId(i) .setEmail(String.valueOf(i)).setName(String.valueOf(i)).setPhone(String.valueOf(i)).build(); byte[] dataByte = person.toByteArray(); byte[] lenByte = ProtoHelper.intToByteArray(dataByte.length); data = new byte[dataByte.length + lenByte.length]; System.arraycopy(lenByte, 0, data, 0, lenByte.length); System.arraycopy(dataByte, 0, data, lenByte.length, dataByte.length); outputStream.write(data); System.out.println("serialize len :" + dataByte.length + ",id:" + person.getId() + ",name:" + person.getName() + ",email:" + person.getEmail() + ",phone:" + person.getPhone()); } outputStream.flush(); outputStream.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }
四、反序列化
因为上述数据量小,这里一次性从文件读出来,就没有设置缓冲区了
/** * 反序列化 * @param path */ public void deSerializeProto(String path) { System.out.println("deSerialize file " + path); try { InputStream inputStream = new FileInputStream(new File(path)); byte[] data = new byte[4096]; int len = 0; while ((len = inputStream.read(data)) > 0) { int index = 0; while (index < len) { byte[] lenByte = new byte[4]; System.arraycopy(data, index, lenByte, 0, 4); int itemLen = ProtoHelper.byteArrayToInt(lenByte); byte[] dataByte = new byte[itemLen]; System.arraycopy(data, index + lenByte.length, dataByte, 0, itemLen); Message.Person person = Message.Person.parseFrom(dataByte); System.out.println("deSerialize len :" + (dataByte.length + 4) + ",id:" + person.getId() + ",name:" + person.getName() + ",email:" + person.getEmail() + ",phone:" + person.getPhone()); index = index + lenByte.length + dataByte.length; } } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }
执行结果:
由于proto跨平台,所以java端序列化后,C端同事也能解码文件,有一定的日志安全性吧
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Proto3的在IDEA+Gradle项目集成
前文介绍了在Android环境中集成,因为需要对序列化数据文件进行反序列化,所以需要一个java脚本,因此才有了此文,基于IDEA+Gradle集成proto网上也有很简便介绍,直接在IDEA中添加proto插件即可,但怕有版本问题,影响后面反序列化,白折腾,故想自己添加,下面都介绍 一、添加IDEA插件方式集成 在IDEA中依次点击"File"-->"Settings"-->"Plugins"-->"Browse repositories"后,输入Protobuf,找到Protobuf Support后安装重启IDEA即可,*.proto文件将会支持高亮语法显示,此方法网上案例很多,不过多介绍 可参考:https://www.cnblogs.com/liugh/p/7505533.html 二、手动添加版本集成 1. 新建Gradle项目 以正常方式在IDEA新建一个Gradle项目即可 2. 项目build.gradle配置 buildscript { repositories { mavenCentral() } dependencies { classpath...
- 下一篇
Java 垃圾收集技术
Java 垃圾收集技术前言在计算机科学中,垃圾收回(GC: garbage collection)是内存自动管理的一种方式,它并不是同Java语言一起诞生的,实际上,早在 1959 年为了简化Lisp语言的手动内存管理,该语言的作者就开始使用了内存自动管理技术。垃圾收集和手动内存管理刚好相反,后者需要编程人员自己去指定需要释放的对象然后将内存归还给操作系统,而前者不需要关心给对象分配的内存回收问题。Java语言使用自动垃圾收集器来管理对象生命周期中的内存,要进行垃圾收集首先需要明确三个问题:1. 哪些内存需要回收、2. 什么时候进行回收、3. 怎么进行内存回收。接下来让我们一起看看Java语言对这些问题是如何处理的。 哪些内存需要回收为了方便管理和跨平台,Java虚拟机规范规定在执行Java程序的时候把它所管理的内存划分为若干个不同的数据区域。这些区域都有着各自不同的用途以及创建和销毁的时间,有的数据区域随着用户线程的启动和结束而建立和销毁,有的区域会随着虚拟机进程的启动和停止而存在和销毁。更多有关运行时数据区域的内容请看Java 运行时数据区域。由于Java运行时数据区域中的程序计数...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Hadoop3单机部署,实现最简伪集群
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- CentOS8安装Docker,最新的服务器搭配容器使用
- Linux系统CentOS6、CentOS7手动修改IP地址
- CentOS7安装Docker,走上虚拟化容器引擎之路
- CentOS8编译安装MySQL8.0.19
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2更换Tomcat为Jetty,小型站点的福音