用于海量数据流的通货紧缩压缩算法

时间:2016-05-19 22:37:54

标签: c++ compression poco-libraries deflate inflate

我有不时获取数据缓冲区的C ++程序,应将其添加到现有的压缩文件中。

我尝试通过从某个文件读取1k块来制作POC,将它们传递给压缩流并在数据结束时解压缩。

我使用Poco :: DeflatingOutputStream将每个块压缩到文件中,并使用Poco :: InflatingOutputStream来检查解压缩后我得到原始文件。

但是,似乎在解压缩流后,我的数据几乎与原始文件完全相同,除了每2个连续的数据块之间我得到一些垃圾字符,例如:à¿_ÿ

这是一个在2个块之间分割的行的示例。原始行看起来像:

elevated=0 path=/System/Library/CoreServices/Dock.app/Contents/MacOS/Dock exist

而解压缩的行是:

elevated=0 path=/System/Libr à¿_ÿary/CoreServices/Dock.app/Contents/MacOS/Dock exist

5月19日19:12:51 PANMMUZNG8WNREM内核[0]:pid = 904 uid = 1873876126 sbit = 0

知道我做错了什么。这是我的POC代码:

int zip_unzip() {  
   std::ostringstream stream1;
   Poco::DeflatingOutputStream gzipper(stream1, Poco::DeflatingStreamBuf::STREAM_ZLIB);

   std::ifstream bigFile("/tmp/in.log");
   constexpr size_t bufferSize = 1024;
   char buffer[bufferSize];
   while (bigFile) {
       bigFile.read(buffer, bufferSize);
       gzipper << buffer;
   }
   gzipper.close();

   std::string zipped_string = stream1.str();
   ////////////////// 
   std::ofstream stream2("/tmp/out.log", std::ios::binary);
   Poco::InflatingOutputStream gunzipper(stream2, InflatingStreamBuf::STREAM_ZLIB);
   gunzipper << zipped_string;
   gunzipper.close();
   return 0;
}

1 个答案:

答案 0 :(得分:0)

好的,我刚刚意识到我使用了&#39;&lt;&lt;&lt;&#39;每个从HugeFile(原始解压缩文件)读取的运算符都没有小心,因为没有空终止符号&#39; / 0&#39;在每个窗口的末尾,我从文件中读取。

这是固定版本:

#include <stdio.h>
#include <fstream>
#include <Poco/DeflatingStream.h>
#include <Poco/Exception.h>
#include <iostream>


int BetterZip()
{
    try {
    // Create gzip file.
    std::ofstream output_file("/tmp/out.gz", std::ios::binary);
    Poco::DeflatingOutputStream output_stream(output_file, Poco::DeflatingStreamBuf::STREAM_GZIP);

    // INPUT
    std::ifstream big_file("/tmp/hugeFile");
    constexpr size_t ReadBufferSize = 1024;
    char buffer[ReadBufferSize];
    while (big_file) {
        big_file.read(buffer, ReadBufferSize);
        output_stream.write(buffer, big_file.gcount());
    }

    output_stream.close();
    } catch (const Poco::Exception& ex) {
        std::cout << "Error :  (error code " << ex.code() << " ("  << ex.displayText() << ")";
        return EINVAL;
    }

    return 0;
}