Ho un problema con la memorizzazione dei dati di Protobuf su disco. L'applicazione che ho utilizza Protocol Buffer per trasferire dati su un socket (che funziona bene), ma quando provo a memorizzare i dati sul disco fallisce. In realtà, il salvataggio dei dati non presenta problemi, ma non riesco a caricarli di nuovo correttamente. Eventuali suggerimenti sarebbero graditi.Buffer di protocollo; salvataggio dei dati sul disco e caricamento del numero di aggiornamento
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);
}
Ho verificato i dati all'interno di questa funzione, il dLista contiene i dati che mi aspetto. I flussi segnalano che non si sono verificati errori e che una quantità ragionevole di byte è stata scritta sul disco. (anche il file è di dimensioni ragionevoli) Ma quando provo a rileggere i dati, non funziona. Inoltre, ciò che è veramente strano, è che se aggiungo più dati a questo file, posso leggere i primi messaggi (ma non quello alla fine).
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);
}
Ovviamente ho omesso parte del codice qui per semplificare tutto. Come nota a margine, ho anche provato a serializzare il messaggio su una stringa & salvando quella stringa tramite CodedOutputStream. Questo non funziona neanche. Ho verificato il contenuto di quella stringa, quindi suppongo che il colpevole debba essere la funzione di streaming.
Questo è un ambiente Windows, C++ con buffer di protocollo e Qt.
Grazie per il vostro tempo!
Perché diavolo stai usando 'new' e chiama esplicitamente i distruttori? Questo non ha assolutamente senso. –
Ho modificato per risolvere questo problema. Non ho idea del perché sia sembrata una buona idea in quel momento. Buona cattura, ma non abbastanza per risolvere il mio problema. – almagest
In realtà hai risolto solo metà problema: l'uso di puntatori e 'nuovo' qui non ha ancora senso. Ma sì, è improbabile che sia correlato al tuo problema. –