如前所述,Writer 将把一个结构化数据写入磁盘,以便其他人来读取。假如我们不使用 Protobuf,其实也有许多的选择。一个可能的方法是将数据转换为字符串,然后将字符串写入磁盘。转换为字符串的方法可以使用 sprintf(),这非常简单。数字 123 可以变成字符串”123”。
这样做似乎没有什么不妥,但是仔细考虑一下就会发现,这样的做法对写 Reader 的那个人的要求比较高,Reader 的作者必须了 Writer 的细节。比如”123”可以是单个数字 123,但也可以是三个数字 1,2 和 3,等等。这么说来,我们还必须让 Writer 定义一种分隔符一样的字符,以便 Reader 可以正确读取。但分隔符也许还会引起其他的什么问题。最后我们发现一个简单的 Helloworld 也需要写许多处理消息格式的代码。
如果使用 Protobuf,那么这些细节就可以不需要应用程序来考虑了。
使用 Protobuf,Writer 的工作很简单,需要处理的结构化数据由 .proto 文件描述,经过上一节中的编译过程后,该数据化结构对应了一个 C++ 的类,并定义在 lm.helloworld.pb.h 中。对于本例,类名为 lm::helloworld。
Writer 需要 include 该头文件,然后便可以使用这个类了。
现在,在 Writer 代码中,将要存入磁盘的结构化数据由一个 lm::helloworld 类的对象表示,它提供了一系列的 get/set 函数用来修改和读取结构化数据中的数据成员,或者叫 field。
当我们需要将该结构化数据保存到磁盘上时,类 lm::helloworld 已经提供相应的方法来把一个复杂的数据变成一个字节序列,我们可以将这个字节序列写入磁盘。
对于想要读取这个数据的程序来说,也只需要使用类 lm::helloworld 的相应反序列化方法来将这个字节序列重新转换会结构化数据。这同我们开始时那个“123”的想法类似,不过 Protobuf 想的远远比我们那个粗糙的字符串转换要全面,因此,我们不如放心将这类事情交给 Protobuf 吧。
程序清单 2 演示了 Writer 的主要代码,您一定会觉得很简单吧?
清单 2. Writer 的主要代码
#include "lm.helloworld.pb.h" … int main(void) { lm::helloworld msg1; msg1.set_id(101); msg1.set_str(“hello”); // Write the new address book back to disk. fstream output("./log", ios::out | ios::trunc | ios::binary); if (!msg1.SerializeToOstream(&output)) { cerr << "Failed to write msg." << endl; return -1; } return 0; } |
Msg1 是一个 helloworld 类的对象,set_id() 用来设置 id 的值。SerializeToOstream 将对象序列化后写入一个 fstream 流。
代码清单 3 列出了 reader 的主要代码。
清单 3. Reader
#include "lm.helloworld.pb.h" … void ListMsg(const lm::helloworld & msg) { cout << msg.id() << endl; cout << msg.str() << endl; } int main(int argc, char* argv[]) { lm::helloworld msg1; { fstream input("./log", ios::in | ios::binary); if (!msg1.ParseFromIstream(&input)) { cerr << "Failed to parse address book." << endl; return -1; } } ListMsg(msg1); … } |
同样,Reader 声明类 helloworld 的对象 msg1,然后利用 ParseFromIstream 从一个 fstream 流中读取信息并反序列化。此后,ListMsg 中采用 get 方法读取消息的内部信息,并进行打印输出操作。
运行结果
运行 Writer 和 Reader 的结果如下:
>writer >reader 101 Hello |
Reader 读取文件 log 中的序列化信息并打印到屏幕上。本文中所有的例子代码都可以在附件中下载。您可以亲身体验一下。
这个例子本身并无意义,但只要您稍加修改就可以将它变成更加有用的程序。比如将磁盘替换为网络 socket,那么就可以实现基于网络的数据交换任务。而存储和交换正是 Protobuf 最有效的应用领域。
分享到:
相关推荐
3. **编写 Writer 和 Reader**: - **Writer**:使用生成的类实例化对象并设置字段值,然后将数据序列化并写入文件。 - **Reader**:从文件中读取字节流,反序列化为对象,并打印其字段值。 #### 四、总结 ...
在"reader and writer---操作系统之课程设计"中,学生可能需要完成以下任务: 1. **模型建立**:创建读者和写者的抽象类或接口,定义它们的行为,如读取、写入和等待操作。 2. **资源管理**:设计一个管理共享资源...
本项目提供了使用信号量解决读写者问题的代码实现,分别在`reader.c`和`writer.c`两个文件中。 首先,让我们了解一下什么是信号量。信号量(Semaphore)是操作系统中的一种同步机制,用于控制多个进程对共享资源的...
在实际使用中,DataX的writer插件通常与reader插件配合工作,reader负责从源数据源读取数据,writer则负责将数据写入目标系统。用户可以通过编写简单的配置文件或利用DataX的API来指定数据同步任务的源和目标,以及...
EMV Reader Writer_EmvREADERwriter_EMV_源码.zip 是一个包含EMV读卡器/写卡器的源代码的压缩包。EMV(Europay, Mastercard, Visa)是一种国际银行卡标准,用于智能卡(也称为芯片卡或IC卡)技术,主要目的是提高...
OFD Reader & Writer 在使用OFDRW前请务必悉知 。 如何clone和预览存在困难,请移步 Talk is cheap,Show me the code. ——Linus Torvalds 像写HTML和Word那样简单的编写OFD。 根据标准实现版式文档OFD库(含有书签...
"excel-io:具有界面实现的Excel Reader和Writer"是一个项目,它提供了用于读取和写入Excel文件的工具,而且这个工具集还包含了用户界面,使得操作更为直观和方便。在IT领域,处理Excel数据是常见的任务,尤其在数据...
DataX插件主要分为Reader和Writer两大类,其中Reader负责从数据源读取数据,而Writer则负责将数据写入目标端。 开发DataX插件时,可以使用Java语言实现,需要遵循一定的开发规范和步骤。开发者在开发过程中,首先...
项目中会用到InputStream和OutputStream进行字节流操作,以及Reader和Writer进行字符流操作。理解如何正确地读取和写入网络数据是学习的重点。 5. **并发与同步**:由于涉及到多个用户同时在线聊天,因此需要理解和...
png-dpi-reader-writer 浏览器上png图像的pHYs块的读取器/写入器。 安装 $ npm install png-dpi-reader-writer 用法 读者 检测PNG图像的宽度,高度和DPI。 const res = await fetch ( srcUrl , { mode : 'cors' } ...
本教程将深入探讨如何使用C#语言来编写TCP客户端应用程序,这将帮助开发者构建能够与服务器进行稳定通信的应用。 首先,了解TCP协议的基本原理是必要的。TCP是一种面向连接的协议,它在数据传输前会建立一个连接,...
OFD Reader & Writer 在使用OFDRW前请务必悉知 。 如何clone和预览存在困难,请移步 Talk is cheap,Show me the code. ——Linus Torvalds 像写HTML和Word那样简单的编写OFD。 根据标准实现版式文档OFD库(含有书签...
writer.addPage(reader.getPage(page_num)) with open(output_file, 'wb') as out_file: writer.write(out_file) # 使用方法 input_files = ['file1.pdf', 'file2.pdf', 'file3.pdf'] output_file = 'merged....
- **Reader/Writer**: 字符流,适合处理文本数据,可能会用到BufferedReader和BufferedWriter。 4. **文本处理** - **StringBuffer/StringBuilder**: 在进行大量字符串拼接时,这两个类比直接使用+操作符更高效。...
Android Studio是Google提供的官方Android开发集成开发环境(IDE),提供了一系列工具,如代码编辑器、调试器、构建工具等,便于开发人员高效地编写和测试应用。 总的来说,CSV_Writer库为Android开发者提供了一种...
通过调用`csv.reader()`和`csv.writer()`,我们可以轻松地遍历CSV文件的行和列,进行添加、删除、修改等操作。例如,要读取CSV文件,我们可以这样做: ```python import csv with open('file.csv', 'r') as f: ...