2012-02-28 3 views
6

Я читаю сжатый файл, используя подталкивания iostreams: Следующие работает отлично:Может увеличить iostreams читать и сжимать gzipped файлы на лету?

namespace io = boost::iostreams; 
    io::filtering_istream in; 
    in.push(boost::iostreams::basic_gzip_decompressor<>()); 
    in.push(io::file_source("test.gz")); 
    stringstream ss; 
    copy(in, ss); 

Однако, я не хочу, чтобы принять удар памяти читать весь файл сжатого в память. Я хочу, чтобы читать файл постепенно.

Например, если у меня есть структуры данных X, который инициализирует себя от IStream,

X x; 
x.read(in); 

терпит неудачу. Предположительно, это связано с тем, что нам придется возвращать символы в поток , если мы делаем частичные потоки. Любые идеи о том, поддерживает ли iostreams, поддерживает ли это?

+0

Would делать такую ​​операцию, как вызов 'GetLine()' 'то сжимающую()' это через работу петли для вас? – user99545

+0

@ user99545: Нет: поскольку X создает себя из двоичных данных. – ATemp

+0

Я не понимаю, почему нет. Я использовал boost iostreams для чтения и записи потоков, сжатых zlib таким образом. – Ferruccio

ответ

1

В соответствии с iostream documentation тип boost::io::filtering_istream происходит от std::istream. То есть, это должно быть возможно передать это везде, где ожидается std::istream&. Если у вас есть ошибки во время выполнения, потому что вам нужно указать unget() или putback() символов, вы должны посмотреть на параметр pback_size, который указывает, сколько символов возвращается максимум. Я не видел в документации, что значение по умолчанию для этого параметра.

Если это не поможет решить вашу проблему, можете ли вы описать вашу проблему точно? По внешнему виду он должен работать.

1

Думаю, вам нужно написать свой собственный фильтр. Например, чтобы прочитать .tar.gz и выходные файлы, содержащиеся, я написал что-то вроде

//using namespace std; 
namespace io = boost::iostreams; 

struct tar_expander 
{ 
    tar_expander() : out(0), status(header) 
    { 
    } 
    ~tar_expander() 
    { 
     delete out; 
    } 

    /* qualify filter */ 
    typedef char char_type; 
    struct category : 
     io::input_filter_tag, 
     io::multichar_tag 
    { }; 

    template<typename Source> 
    void fetch_n(Source& src, std::streamsize n = block_size) 
    { 
      /* my utility */ 
      .... 
    } 

    // Read up to n filtered characters into the buffer s, 
    // returning the number of characters read or -1 for EOF. 
    // Use src to access the unfiltered character sequence 
    template<typename Source> 
    std::streamsize read(Source& src, char* s, std::streamsize n) 
    { 
     fetch_n(src); 
     const tar_header &h = cast_buf<tar_header>(); 
     int r; 

     if (status == header) 
     { 
      ... 
     } 
     std::ofstream *out; 
     size_t fsize, stored; 

     static const size_t block_size = 512; 
     std::vector<char> buf; 

     enum { header, store_file, archive_end } status; 
    } 
} 

Моя функция read(Source &...) при вызове получает распакованные текст. Чтобы использовать фильтр:

ifstream file("/home/..../resample-1.8.1.tar.gz", ios_base::in | ios_base::binary); 
io::filtering_streambuf<io::input> in; 
in.push(tar_expander()); 
in.push(io::gzip_decompressor()); 
in.push(file); 
io::copy(in, cout); 
Смежные вопросы