【问题标题】:Example of Boost IOStream to create a zip file?创建 zip 文件的 Boost IOStream 示例?
【发布时间】:2012-02-08 19:43:05
【问题描述】:

我一直在寻找一种在 C++ 中创建 zip 文件的良好、可移植的方法,但一直未能成功。我在不同的地方读到它可以使用 Boost IOstream 库,但我在参考中找不到任何源代码甚至文档:

http://www.boost.org/doc/libs/1_48_0/libs/iostreams/doc/index.html

有人有好的参考吗?我在谷歌上搜索了很多,但没有想出多少。

【问题讨论】:

    标签: c++ boost


    【解决方案1】:

    我不认为 boost::iostreams 可以打开 zip 文件。见Unziping a zip file with boost and Visual C++ 2005

    boost::iostreams 可用于使用 zlib、gzip 或 bzip2 压缩流或单个文件。您可以在这里找到一些示例:

    但是,它无法读取 zip 文件中的目录信息。

    另一方面,您需要使用第三方库:zlib 和 bzip2 来编译 boost。请参阅installation information

    【讨论】:

    • 感谢您的解释。您可能认为有一种无需大量代码即可轻松创建 zip 文件的简便方法。
    【解决方案2】:

    我编写了一个简单的 zip 文件生成器,允许与 iostreams 一起使用。 它包含在 partio 库中 https://github.com/wdas/partio/blob/master/src/lib/io/ZIP.h https://github.com/wdas/partio/blob/master/src/lib/io/ZIP.cpp

    例如,您可以通过以下方式创建一个包含两个文件的 zip 文件

    ZipFileWriter zip("foo.zip");
    std::ostream* o = zip.Add_File("test.txt");
    *o << "look a zip file" << std::endl;
    delete o;
    std::ostream* o2 = zip.Add_File("test2.txt");
    *o2 << "look another file" << std::endl;
    delete o2;
    

    然后可以通过这样做来读取文件

    ZipFileReader zip("foo.zip");
    std::istream* i = zip.Get_File("test.txt");
    std::string foo;
    *i >> foo;
    std::cout << foo << std::endl;
    delete i;
    

    【讨论】:

      【解决方案3】:

      也许它不是一个 zip 文件,而是一个压缩文件,如果它可以帮助你的意图。 实际上,我对此进行了测试:

      #include <fstream>
      #include <sstream>
      #include <iostream>
      #include <boost/iostreams/filtering_streambuf.hpp>
      #include <boost/iostreams/copy.hpp>
      #include <boost/iostreams/filter/zlib.hpp>
      
      TEST(MyTests, SaveZipFile)
      {
          using namespace std;
      
          ofstream file("a.z", ios_base::out | ios_base::binary);
          boost::iostreams::filtering_streambuf<boost::iostreams::output> out;
          out.push(boost::iostreams::zlib_compressor());
          out.push(file);
      
          stringstream sstr{"nihao"};
      
      
          boost::iostreams::copy(sstr, out);
      }
      
      TEST(MyTests, OpenZipFile)
      {
          using namespace std;
          ifstream file("a.z", ios_base::in | ios_base::binary);
          boost::iostreams::filtering_streambuf<boost::iostreams::input> in;
          in.push(boost::iostreams::zlib_decompressor());
          in.push(file);
      
          stringstream sstr;
          boost::iostreams::copy(in, sstr);
          cout << sstr.str() << endl;
          ASSERT_EQ(sstr.str(), string("nihao"));
      }
      

      【讨论】:

        【解决方案4】:

        这是无缝处理 zip 文件的有用流类!

        但要注意文件 ZIP.cpp 中有一个小错误,请考虑:第 191 行。阅读

        char* buf=new char[std::max(comment_length,std::max(filename_length,extra_length))];
        istream.read(buf,filename_length);
        buf[filename_length]=0;
        

        这忽略了缓冲区需要一个更多字符空间用于终止符的事实(第 193 行),这可能会破坏堆!因此第 191 行应该是

        char* buf=new char[std::max(comment_length,std::max(static_cast<unsigned short>(filename_length+1),extra_length))];
        

        所以,如果你打算使用这个类,你应该考虑修复这个错误。没问题。

        【讨论】:

          猜你喜欢
          • 2011-04-09
          • 2015-10-06
          • 1970-01-01
          • 2011-05-15
          • 1970-01-01
          • 1970-01-01
          • 2012-10-16
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多