如何实际看到 protobuf 在网络上或文件中传递一些字节? 步骤:

问题描述

我是 protobuf 的新手,想尝试一下,通过网络或文件传递一些数据,例如

2-byte unsigned int: 15
2-byte unsigned int: 15 and -1
4-byte unsigned int: 256,and then a string "Peter"
4-byte unsigned int: 256,and then two strings "Peter","Mary"
4-byte signed int: (3,4) as a point
4-byte signed int: a point above twice,such as (3,4) and (10,11) as a line
4-byte signed int and a string: the line above,and a name for this line

可以将字节由 Python / Ruby 写入文件中,然后由 JavaScript 读回吗? (也可以全部用 JavaScript 编写)。

我认为能够在本地网站上传递它可能要复杂一些?如果是这样,将其写入文件并能够读回就可以了。怎么可能做到?

解决方法

我发现使用protobuf.js简单很多,而且我们不需要使用protoc这个编译器命令行工具。我发现很难让 Python 或 C++ 版本工作,因为它涉及 Python2 与 Python3,以及 pip 和缺少的库。

所以只需遵循 the protobuf.js website,我已经包含了使其工作的基本最低要求。

我们可以阅读有关 how to make a .proto file from Google's website 的所有内容。

步骤:

创建一个空文件夹并安装protobufjs。如果需要,请使用 Google 搜索 nvm(可选)以及 Node.js 和 npm。

mkdir TryProtobufJS
cd TryProtobufJS
npm i protobufjs

现在,创建这 3 个文件:

// awesome.proto
package awesomepackage;
syntax = "proto3";

message AwesomeMessage {
    int32 num = 1;
    string awesome_field = 20; // becomes awesomeField
}
// write.js

const fs = require("fs");
const protobuf = require("protobufjs");

protobuf.load("awesome.proto",function (err,root) {
  if (err) throw err;

  const AwesomeMessage = root.lookupType("awesomepackage.AwesomeMessage");

  const payload = { num: 15,awesomeField: "ABC" };
  console.log("payload",payload);

  const errMsg = AwesomeMessage.verify(payload);
  if (errMsg) throw Error(errMsg);

  const message = AwesomeMessage.create(payload); // or use .fromObject if conversion is necessary

  // Encode a message to an Uint8Array (browser) or Buffer (node)
  const buffer = AwesomeMessage.encode(message).finish();

  console.log(buffer);
  fs.writeFileSync("awesome.dat",buffer);
});
// read.js

const fs = require("fs");
const protobuf = require("protobufjs");

protobuf.load("awesome.proto",root) {
  if (err) throw err;

  const AwesomeMessage = root.lookupType("awesomepackage.AwesomeMessage");

  const buffer = fs.readFileSync("awesome.dat");
  console.log(buffer);

  // Decode an Uint8Array (browser) or Buffer (node) to a message
  const message = AwesomeMessage.decode(buffer);

  // Convert the message back to a plain object
  const object = AwesomeMessage.toObject(message,{
    longs: String,enums: String,bytes: String,// see ConversionOptions
  });
  console.log("object",object);
});

现在运行文件 write.js

node write.js

它会创建一个数据文件:awesome.dat

# screen output

payload { num: 15,awesomeField: 'ABC' }
<Buffer 08 0f a2 01 03 41 42 43>

在 Mac 上,你可以 hex dump 来查看它:

hexdump -C awesome.dat

现在,要“取回数据”,请使用

node read.js
# screen output

<Buffer 08 0f a2 01 03 41 42 43>
object { num: 15,awesomeField: 'ABC' }

如果我使用 Node.js v14,出于某种原因,它在 MacBook Air M1 上对我不起作用,但 Node v15 和 v16 起作用了。

另外,注意我们在Node.js中写文件和读文件的时候,没有指定编码,原因如下:

  1. writeFileSync:如果数据是缓冲区,则忽略编码选项。
  2. readFileSync:如果指定了编码选项,则此函数返回一个字符串。否则它返回一个缓冲区。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...