微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

协议缓冲区 ParseFromString 函数未在 Python 作家读者

如何解决协议缓冲区 ParseFromString 函数未在 Python 作家读者

我正在测试协议缓冲区并尝试读取 csv 文件,对其进行序列化并将输出写入二进制文件,然后使用 ParseFromString 读取二进制文件。我能够序列化和写入二进制文件,但是在读取它时会给出一个索引越界异常,或者在其他情况下它只输出二进制文件的最后一行,它会跳过它之前的所有内容

我的消息很简单,它有两个字段,时间和度量使用。

Syntax="proto3";

message excelData {

string time=1;
string meterusage=2;
}

序列化和写入二进制文件代码如下:

import metric_pb2 
import sys
from csv import reader
 

excel_data=metric_pb2.excelData()

with open('out.bin','wb') as f:
    with open('data.csv','r') as read_obj:
        csv_reader = reader(read_obj)
        header = next(csv_reader)
        if header != None:
            for row in csv_reader:
                excel_data.time=row[0]
                excel_data.meterusage=row[1]
                f.write(excel_data.SerializetoString())

f.close()
read_obj.close()

麻烦的部分如下:

方法 1:这只返回二进制文件的最后一行。它会跳过它之前的所有内容

Just one row in the answer set as opposed to the entire binary file

excel_data=metric_pb2.excelData()

with open('out.bin','rb') as f:
    content=f.read()
    excel_data.ParseFromString(content)
    print(excel_data.time)
    print(excel_data.meterusage)

方法 2:如果我像上面的 csv 文件一样读取序列化的二进制文件,它会给我一个索引越界错误。我的倾向是,二进制文件可能是字节数据并且不包含字符串数据类型,因此会出现此错误

使用 message.ParseFromString() 读取这个二进制文件的正确方法是什么,因为通过循环读取它不起作用,也不完整地读取它?我创建的二进制文件的快照如下:

Binary output

解决方法

你成功了吗?

这里有一个 hacky 解决方案(根据 streaming multiple messages 的 Protobuf 技术)将(变量!)消息长度写为每条记录之前的字节。

作家

import metric_pb2
import sys

from csv import reader

excel_data = metric_pb2.excelData()

with open('out.bin','wb') as f:
    with open('data.csv','r') as read_obj:
        csv_reader = reader(read_obj)
        header = next(csv_reader)
        if header != None:
            for row in csv_reader:
                excel_data.time = row[0]
                excel_data.meterusage = row[1]
                bytes = excel_data.SerializeToString()
                # Write the message's integer length as bytes
                f.write(len(bytes).to_bytes(1,sys.byteorder))
                # Write the message itself as bytes
                f.write(bytes)

f.close()
read_obj.close()

产生:

00000000: 1c 0a13 3230 3231 2d30 312d 3031 2030 303a 3030 3a30 3012 0535 342e 3635  ...2021-01-01 00:00:00..54.65
00000010: 1c 0a13 3230 3231 2d30 312d 3031 2030 303a 3030 3a30 3012 0535 352e 3138  ...2021-01-01 00:00:00..55.18
00000030: 1b 0a13 3230 3231 2d30 312d 3031 2030 303a 3030 3a30 3012 0435 352e 38    ...2021-01-01 00:00:00..55.8

注意 1c == 28(因为 54.6555.18)和 1b == 27(因为 55.8

读者

import metric_pb2
import sys

excel_data = metric_pb2.excelData()

with open('out.bin','rb') as f:
    while True:
        # Read the message's length as bytes and convert it to an integer
        len = int.from_bytes(f.read(1),sys.byteorder)
        # Read that number of bytes as the message bytes
        bytes = f.read(len)
        if not bytes:
            break

        excel_data.ParseFromString(bytes)
        print("[{time}] {meterusage}".format(
            time=excel_data.time,meterusage=excel_data.meterusage))

产生:

[2021-01-01 00:00:00] 54.65
[2021-01-01 00:00:00] 55.18
[2021-01-01 00:00:00] 55.8
[2021-01-01 00:00:00] 56.0
[2021-01-01 00:00:00] 63.52
[2021-01-01 00:00:00] 78.1

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?