昨天在弄protobuf写入和读取文件的东西,简单写下过程中遇到的坑吧。
刚开始尝试使用源码安装protobuf,可是每一次都会卡在最后sudo make install的时候提示operation not permitted,多次按照网上给出的方法尝试无果之后,决定采用brew直接安装,关于brew安装的方式网上都有教程,brew安装protobuf的命令是
brew install protobuf
需要注意的是这个命令貌似会把protobuf安装在/usr/local/bin下面,不过查看PATH可以发现这个路径是在系统路径下面的。
下面参考网友给出的工程实例构建了一个工程
https://blog.csdn.net/wanxuexiang/article/details/90050049blog.csdn.netmain.cpp
#include <iostream>
#include <vector>
#include <algorithm>
#include "test.pb.h"
#include <google/protobuf/text_format.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <string>
#include <fstream>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
int main(void )
{
//1、序列化 填写基本的配置项
msgType:: ProtoTest cls_proto_test1;
cls_proto_test1.set_int32_test(123);
cls_proto_test1.set_str_test("wanxuexiang");
cls_proto_test1.add_dou_test(56.023);
cls_proto_test1.add_dou_test(78.023);
msgType::ProtoTestSub* pcls_temp = cls_proto_test1.add_sub_test();
pcls_temp->set_test1(12);
pcls_temp->set_test2("zxcvbnm");
pcls_temp = cls_proto_test1.add_sub_test();
pcls_temp->set_test1(34);
pcls_temp->set_test2("asdfghjkl");
cls_proto_test1.set_eunm_test(msgType::TEST0);
//protobuf调试打印函数 打印成字符串
std::cout << "*******************" << std::endl;
cls_proto_test1.PrintDebugString();
std::cout << "*******************" << std::endl;
//2、将配置写入文件之中
std::string str_proto_test1;
google::protobuf::TextFormat::PrintToString(cls_proto_test1, &str_proto_test1);
std::ofstream file_proto_test1;
file_proto_test1.open("file_proto_test1.cfg", std::ios::out|std::ios_base::ate);
if (!file_proto_test1.is_open())
{
fprintf(stderr, "open file_proto_test1.cfg failn");
return -1;
}
file_proto_test1 << str_proto_test1;
file_proto_test1.flush();
file_proto_test1.close();
system("cat file_proto_test1.cfg");
//2、从配置文件中读取数据
int fd = open("file_proto_test1.cfg", O_RDONLY);
if (fd < 0)
{
printf("file_proto_test1.cfg:%s n",strerror(errno));
return 0;
}
google::protobuf::io::FileInputStream fileInput(fd);
fileInput.SetCloseOnDelete(true);
msgType::ProtoTest cls_proto_test2;;
google::protobuf::TextFormat::Parse(&fileInput, &cls_proto_test2);
//protobuf调试打印函数 打印成字符串
std::cout << "*******************" << std::endl;
cls_proto_test2.PrintDebugString();
msgType::ProtoTestSub cls_temp;
std::cout << "*******************" << std::endl;
for(int i = 0;i < cls_proto_test2.sub_test_size();i++)
{
cls_temp = cls_proto_test2.sub_test(i);
cls_temp.PrintDebugString();
}
return 0;
}
CMakeLists.txt
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
PROJECT(main)
SET(SRC_LIST main.cpp)
ADD_COMPILE_OPTIONS(-std=c++11)
# Find required protobuf package
FIND_PACKAGE(Protobuf REQUIRED)
IF(PROTOBUF_FOUND)
MESSAGE(STATUS "protobuf library found")
ELSE()
MESSAGE(FATAL_ERROR "protobuf library is needed but cant be found")
ENDIF()
INCLUDE_DIRECTORIES(${PROTOBUF_INCLUDE_DIRS}) # /usr/local/include
ADD_SUBDIRECTORY(proto)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}/proto)
LINK_LIBRARIES(proto)
ADD_EXECUTABLE(main ${SRC_LIST})
proto/test.proto
syntax = "proto3";
package msgType;
enum EnumTest
{
TEST0 = 0x00;
TEST1 = 0x01;
TEST2 = 0x02;
TEST3 = 0x03;
}
message ProtoTestSub
{
int32 test1 = 1;
string test2 = 2;
}
message ProtoTest
{
int32 int32_test = 1;
string str_test = 2;
repeated double dou_test = 3;
repeated ProtoTestSub sub_test = 4;
EnumTest eunm_test = 5;
bytes bytes_test = 6;
}
proto/CMakeLists.txt
PROTOBUF_GENERATE_CPP(PROTO_SRCS PROTO_HDRS test.proto)
ADD_LIBRARY(proto ${PROTO_SRCS})
TARGET_LINK_LIBRARIES(proto ${PROTOBUF_LIBRARIES}) # /usr/local/lib/libprotobuf.dylib