protobuf 之 Varint

这篇具有很好参考价值的文章主要介绍了protobuf 之 Varint。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

varint 背景

Varint 是一种紧凑的表示数字的方法。它用一个或多个字节来表示一个数字,值越小的数字使用越少的字节数。这能减少用来表示数字的字节数。
Varint 中的每个 byte 的最高位 bit 有特殊的含义,如果该位为 1,表示后续的 byte 也是该数字的一部分,如果该位为 0,则结束。其他的 7 个 bit 都用来表示数字。
如下图:(注意到最终计算前将两个 byte 的位置相互交换过一次,这是因为 Google Protocol Buffer 字节序采用 little-endian 的方式)
protobuf 之 Varint,protobuf,python,C++,protobuf,c++,python,varint,varint32

举例

例如:
1、整数 300 的表示,需要两个字节:
1010 1100 0000 0010

2、整数 1 的表示,仅需一个字节:
0000 0001

占用字节数

采用 Varint,对于小的 int32 类型数字,可以用 1 个 byte 来表示;但是也有不好的一面,对于大数字来说依旧采用 Varint 表示法时,大到会需要 5 个 byte 来表示。
所以用 Varint 表示 int32 数字,占 1~ 5 Byte。如下:

int32 MAX 0111 1111 1111 1111 1111 1111 1111 1111

Varint32 1111 1111 1111 1111 1111 1111 1111 1111 0000 0111

即使如此从统计的角度来说,一般不会所有的消息中的数字都是大数,因此大多数情况下,采用 Varint 后,可以用更少的字节数来表示数字信息。

使用注意:

1、写Varint时,可以不关注占用的字节长度范围
2、读取Varint时,必须以最大长度来读取解析。否则内部解析Varint数据时会越界 ( 比如:数据实际占用了3个字节,但是你只读2个字节来解析数据时,第二个字节并非数据末尾字节,proto 库函数会继续解析直到遇到末尾标志。但是在库函数继续解析时会发生越界)

举例 Varint 的读写

eg: cpp 写 Varint

// cpp
	std::ofstream output;
	output.open("tmp.log");
	/*
	*** 此处忽略 n 行无关代码
	*/
	{
        google::protobuf::io::OstreamOutputStream raw_output(&output);
		google::protobuf::io::CodedOutputStream coded_output(&raw_output);
        
		auto user_data = response->userdata();// 简略: response 为proto格式
        int fid = (int)user_data;
        coded_output.WriteVarint32(fid); // 文件中写入 varint32 类型 id 数据
        coded_output.WriteVarint32(response->ByteSizeLong());// 文件中写入 varint32 类型 response 长度
        response->SerializeToCodedStream(&coded_output);// 文件中写入 response 数据
	}

eg:python 读 varint文章来源地址https://www.toymoban.com/news/detail-816424.html

# python

	# 忽略 n 行无关代码
	
	fid_buf = file.read(5) # 读取文件5个字节
    if not fid_buf:
          return -1, None

    fid, new_pos = _DecodeVarint32(fid_buf, 0) #从5个字节中获取fid,并返回实际Varint占用长度
    offset = len(fid_buf) - new_pos
    
    if offset != 0:
        file.seek(-offset, 1)

    buf = file.read(5) # 再读取文件5个字节
    if not buf:
        return -1, None
    msg_len, new_pos = _DecodeVarint32(buf, 0) #从5个字节中获取 response 长度,并返回实际Varint占用长度
	
    msg_buf = file.read(msg_len)# 读取 response 

到了这里,关于protobuf 之 Varint的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • protobuf 的bug:ImportError_ cannot import name ‘builder‘ from ‘google.protobuf.internal‘

    今天了解到有一个很强大的数据分析工具streamlit,下载安装完发现启动不了……没错就是本文的bug. 什么是 protobuf ? Protocol Buffers 是 Google 开发的一种数据交换格式,采用了一种类似于 XML 的简单的语法,用于定义数据结构,并且可以将这些结构序列化为二进制文件,以便在不

    2024年01月23日
    浏览(45)
  • Protobuf数据交互实战

    \\\"no one gonna make me down\\\"          在之前呢,我们介绍了什么protobuf以及它的语法、数据类型。 一句老话说得好,\\\"多说不练,假把式!\\\"。因此,本篇会选择以protobuf的语法,完成一个简易的通讯录,一个是文件版的,一个是网络版的。这样才能让我亲切地感受到,protobuf以

    2024年02月15日
    浏览(31)
  • MsgPack和Protobuf

    MsgPack可以在C++下序列化类,Protobuf只能在C#下序列化类 C++只要#include msgpack.hpp就能直接用,不用链接库,也不用包含CPP文件。 项目文件夹执行 Cannot read property \\\'Buffer\\\' of undefined 看这个: Creator 3.x npm包 一些坑的解决方法(新手向) - Creator 3.x - Cocos中文社区 在这个路径下建一个

    2024年02月05日
    浏览(8)
  • protobuf概览

    protobuf是由谷歌推出的二进制序列化与反序列化库对象。也是著名GRPC的底层依赖,它独立于平台及语言的序列化与反序列化标准库。 相关网址 protobuf IDL描述 protobuf 开源库 grpc-知乎 grpc官方示例 安装protobuf可以使用vcpkg进行简易安装依赖,protoc.exe则会安装在installedx64-windows

    2024年02月11日
    浏览(3)
  • idea使用protobuf

    本文参考:https://blog.csdn.net/m0_37695902/article/details/129438549 再次感谢分享 什么是 protobuf ? Protocal Buffers(简称protobuf)是谷歌的一项技术,用于结构化的数据序列化、反序列化。 由于protobuf是跨语言的,所以用不同的语言序列化对象后,生成一段字节码,之后可以其他任何语言反

    2024年02月14日
    浏览(28)
  • ubuntu卸载protobuf

    1、先查看protobuf的版本:protoc --version 2、查找protobuf的位置:which protoc,我的电脑上是/usr/local/bin/protoc 3、执行sudo rm /usr/local/bin/protoc //可执行文件 4、sudo rm -rf /usr/local/include/google //头文件 5、sudo rm -rf /usr/local/lib/libproto* //库文件

    2024年02月05日
    浏览(39)
  • Protobuf编码规则

    该表显示了在  .proto  文件中指定的类型,以及自动生成的类中的相应类型: .proto Type Notes C++ Type Java/Kotlin Type[1] Java/Kotlin 类型 [1] Python Type[3] Go Type Ruby Type C# Type PHP Type Dart Type double double double float float64 Float double float double float float float float float32 Float float float double int32 var

    2024年02月02日
    浏览(27)
  • Protobuf 简介

    protobuf (protocol buffer) 是谷歌内部的混合语言数据标准。通过将结构化的数据进行序列化(串行化),用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。通常说的protobuf包括以下三点: 是一种二进制数据交换格式。支持不同与语言例如C++、j

    2024年02月16日
    浏览(22)
  • 3.netty和protobuf

    1.ChannelGroup可以免遍历由netty提供,覆盖remove方法即可触发删除channel 2.群聊私聊 13.群聊私聊简单原理图 3.netty心跳检测机制,客户端对服务器有没有读写(读,写空闲) //IdleStateHandler(3,5,7,TimeUnite.SECONDS)是netty提供的检测状态的处理器,也加到pipeline,读,写,读写都没有 //并在handler类实现

    2024年02月14日
    浏览(37)
  • protobuf版本不兼容问题

    [libprotobuf FATAL third_party/protobuf-lite/common.cc:87] This program was compiled against version 3.13.0 of the Protocol Buffer runtime library, which is not compatible with the installed version (3.14.0). Contact the program author for an update. If you compiled the program yourself, make sure that your headers are from the same version of Protocol Buffe

    2024年02月05日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包