Tengo un problema con el almacenamiento de datos de Protobuf en el disco. La aplicación que tengo usa Protocol Buffer para transferir datos a través de un socket (que funciona bien), pero cuando intento almacenar los datos en el disco, falla. En realidad, el guardado de datos informa que no hay problemas, pero parece que no puedo volver a cargarlos correctamente. Cualquier consejo sería apreciado gustosamente.Buffers de protocolo; guardar datos en el disco y cargar el número de vuelta
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);
}
He verificado los datos dentro de esta función, la dList contiene los datos que espero. Las secuencias informan que no se producen errores y que se escribieron una cantidad razonable de bytes en el disco. (también el archivo es de tamaño razonable) Pero cuando trato de leer los datos, no funciona. Además, lo que es realmente extraño, es que si agrego más datos a este archivo, puedo leer los primeros mensajes (pero no el que está al final).
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);
}
Obviamente he omitido parte del código aquí para simplificarlo todo. Como nota al margen, también he intentado serializar el mensaje en una cadena &, guardar esa cadena a través de CodedOutputStream. Esto tampoco funciona. Aunque he verificado el contenido de esa cadena, así que supongo que las funciones de transmisión deben ser culpables.
Este es un entorno de Windows, C++ con búferes de protocolo y Qt.
¡Gracias por su tiempo!
¿Por qué diablos estás usando 'new' y llamando explícitamente a los destructores? Eso no tiene ningún sentido en absoluto. –
He corregido para solucionar este problema. No tengo idea de por qué parecía una buena idea en ese momento. Buena captura, pero no lo suficiente como para solucionar mi problema. – almagest
En realidad, solo resolvió la mitad del problema: usar punteros y 'nuevo' aquí todavía no tiene sentido. Pero sí, es poco probable que esté relacionado con tu problema. –