después de algunos días de experimentar con Buffers de Protocolo intenté comprimir los archivos . Con Python esto es bastante simple de hacer y no requiere ningún juego con transmisiones.Ejemplo de trabajo simple de GzipOutputStream y GzipInputStream con Buffers de Protocolo
Como la mayoría de nuestro código está escrito en C++, me gustaría comprimir/ descomprimir archivos en el mismo idioma. He intentado la biblioteca gzip impulso, pero no pude conseguir que funcione (no comprimir):
int writeEventCollection(HEP::MyProtoBufClass* protobuf, std::string filename, unsigned int compressionLevel) {
ofstream file(filename.c_str(), ios_base::out | ios_base::binary);
filtering_streambuf<output> out;
out.push(gzip_compressor(compressionLevel));
out.push(file);
if (!protobuf->SerializeToOstream(&file)) {//serialising to wrong stream I asume
cerr << "Failed to write ProtoBuf." << endl;
return -1;
}
return 0;
}
He buscado ejemplos que utilizan GzipOutputStream and GzipInputStream con Protocol Buffers pero no pude encontrar una ejemplo de trabajo.
Como podrá darse cuenta por ahora soy un principiante en el mejor de arroyos y apreciaría realmente un ejemplo completamente de trabajo como en http://code.google.com/apis/protocolbuffers/docs/cpptutorial.html (tengo mi address_book, ¿Cómo se guardan en un archivo gziped?)
Gracias de antemano.
EDITAR: Ejemplos de trabajo.
Ejemplo 1 después de la respuesta aquí en StackOverflow
int writeEventCollection(shared_ptr<HEP::EventCollection> eCollection,
std::string filename, unsigned int compressionLevel) {
filtering_ostream out;
out.push(gzip_compressor(compressionLevel));
out.push(file_sink(filename, ios_base::out | ios_base::binary));
if (!eCollection->SerializeToOstream(&out)) {
cerr << "Failed to write event collection." << endl;
return -1;
}
return 0;
}
Ejemplo 2 siguiente respuesta en Google's Protobuf discussion group:
int writeEventCollection2(shared_ptr<HEP::EventCollection>
eCollection, std::string filename,
unsigned int compressionLevel) {
using namespace google::protobuf::io;
int filedescriptor = open(filename.c_str(), O_WRONLY | O_CREAT | O_TRUNC,
S_IREAD | S_IWRITE);
if (filedescriptor == -1) {
throw "open failed on output file";
}
google::protobuf::io::FileOutputStream file_stream(filedescriptor);
GzipOutputStream::Options options;
options.format = GzipOutputStream::GZIP;
options.compression_level = compressionLevel;
google::protobuf::io::GzipOutputStream gzip_stream(&file_stream,
options);
if (!eCollection->SerializeToZeroCopyStream(&gzip_stream)) {
cerr << "Failed to write event collection." << endl;
return -1;
}
close(filedescriptor);
return 0;
}
Algunos comentarios sobre el rendimiento (lectura formato actual y redactar protobuf 11146 archivos): Ejemplo 1:
real 13m1.185s
user 11m18.500s
sys 0m13.430s
CPU usage: 65-70%
Size of test sample: 4.2 GB (uncompressed 7.7 GB, our current compressed format: 7.7 GB)
Ejemplo 2:
real 12m37.061s
user 10m55.460s
sys 0m11.900s
CPU usage: 90-100%
Size of test sample: 3.9 GB
Parece que el método de Google utiliza la CPU de manera más eficiente, es ligeramente más rápido (aunque espero que esto sea dentro de la precisión) y produce un conjunto de datos ~ 7% más pequeño con el mismo ajuste de compresión.
Tenga en cuenta que el problema fundamental aquí no está relacionado con los búferes de protocolo, cualquier ejemplo de "escribir/ejecutar gzip a través de una secuencia" debería funcionar. –