Darkenor
Darkenor

Reputation: 4449

Example of Boost IOStream to create a zip file?

I've been looking for a good, portable way to create a zip file in C++ and been coming up short. I've read in various places that its' possible to use the Boost IOstream library, but I can't find any source code or even documentation on it in the reference:

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

Does anybody have a good reference? I've done a whole lot of Googling and not come up with much.

Upvotes: 9

Views: 24571

Answers (4)

Michaelzh
Michaelzh

Reputation: 490

Maybe it's not a zip file, but rather a compressed file, if it otherwise can help with your intention. Actually, I tested this:

#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"));
}

Upvotes: 3

aselle
aselle

Reputation: 639

I wrote a simple zip file maker that allows use with iostreams. It's included in the partio library https://github.com/wdas/partio/blob/master/src/lib/io/ZIP.h https://github.com/wdas/partio/blob/master/src/lib/io/ZIP.cpp

For example you can create a zip file with two files by doing

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;

And then could read a file by doing

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

Upvotes: 4

Don Pedro
Don Pedro

Reputation: 11

This is a useful streamclass for seamless handling of zip-files!

But beware that there's a small bug in file ZIP.cpp, consider: Lines 191ff. read

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

This neglects the fact that the buffer needs one more char space for the terminator (line 193), possibly corrupting the heap! Thus line 191 should read

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

So, if you're going to use this class you should consider fixing this bug. It's no hassle.

Upvotes: 0

J. Calleja
J. Calleja

Reputation: 4905

I do not think boost::iostreams can open a zip file. See Unziping a zip file with boost and Visual C++ 2005.

boost::iostreams can be used to compress streams or single files using zlib, gzip or bzip2. You may find some examples here:

However, it can not read the directory information inside a zip file.

On the other hand, you need to compile boost using third party libraries: zlib and bzip2. See the installation information.

Upvotes: 9

Related Questions