[英]Protocol Buffers; saving data to disk & loading back issue
我有一個將Protobuf數據存儲到磁盤的問題。 我使用協議緩沖區通過套接字傳輸數據的應用程序(工作正常),但當我嘗試將數據存儲到磁盤時它失敗。 實際上,保存數據報告沒有問題,但我似乎無法再次正確加載它們。 任何提示都將很高興。
void writeToDisk(DataList & dList)
{
// open streams
int fd = open("serializedMessage.pb", O_WRONLY | O_CREAT);
google::protobuf::io::ZeroCopyOutputStream* fileOutput = new google::protobuf::io::FileOutputStream(fd);
google::protobuf::io::CodedOutputStream* codedOutput = new google::protobuf::io::CodedOutputStream(fileOutput);
// save data
codedOutput->WriteLittleEndian32(PROTOBUF_MESSAGE_ID_NUMBER); // store with message id
codedOutput->WriteLittleEndian32(dList.ByteSize()); // the size of the data i will serialize
dList.SerializeToCodedStream(codedOutput); // serialize the data
// close streams
delete codedOutput;
delete fileOutput;
close(fd);
}
我已經驗證了這個函數里面的數據,dList包含了我期望的數據。 流報告沒有發生錯誤,並且將合理數量的字節寫入磁盤。 (也是文件大小合理)但是當我嘗試回讀數據時,它不起作用。 而且,真正奇怪的是,如果我將更多數據附加到此文件,我可以讀取第一條消息(但不是最后的消息)。
void readDataFromFile()
{
// open streams
int fd = open("serializedMessage.pb", O_RDONLY);
google::protobuf::io::ZeroCopyInputStream* fileinput = new google::protobuf::io::FileInputStream(fd);
google::protobuf::io::CodedInputStream* codedinput = new google::protobuf::io::CodedInputStream(fileinput);
// read back
uint32_t sizeToRead = 0, magicNumber = 0;
string parsedStr = "";
codedinput->ReadLittleEndian32(&magicNumber); // the message id-number i expect
codedinput->ReadLittleEndian32(&sizeToRead); // the reported data size, also what i expect
codedinput->ReadString(&parsedstr, sizeToRead)) // the size() of 'parsedstr' is much less than it should (sizeToRead)
DataList dl = DataList();
if (dl.ParseFromString(parsedstr)) // fails
{
// work with data if all okay
}
// close streams
delete codedinput;
delete fileinput;
close(fd);
}
顯然我在這里省略了一些代碼來簡化一切。 作為旁注,我還嘗試將消息序列化為字符串並通過CodedOutputStream保存該字符串。 這也不起作用。 我已經驗證了該字符串的內容,所以我猜罪魁禍首必須是流函數。
這是一個Windows環境,帶有協議緩沖區和Qt的c ++。
感謝您的時間!
讀取失敗是因為沒有打開文件以便使用O_BINARY進行讀取 - 將文件更改為打開並且它可以正常工作:
int fd = open("serializedMessage.pb", O_RDONLY | O_BINARY);
根本原因與此處相同:“ read()僅從文件中讀取幾個字節 ”。 您很可能在protobuf文檔中跟隨一個示例,它以相同的方式打開文件,但是當它遇到文件中的特殊字符時,它會在Windows上停止解析。
此外,在更新版本的庫中,您可以使用protobuf::util::ParseDelimitedFromCodedStream
來簡化讀取大小+有效負載對。
......問題可能很古老,但問題仍然存在,這個答案幾乎可以肯定是對原始問題的解決。
試着用
codedinput->readRawBytes
ReadString
insead
和
dl.ParseFromArray
而不是ParseFromString
不太熟悉協議緩沖區,但ReadString
可能只讀取strine
類型的strine
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.