2015-04-11 2 views
4

Я использую boost :: iostreams :: mapped_file_source для чтения текстового файла из определенной позиции в определенную позицию и для управления каждой строкой (скомпилирован с использованием g ++ -Wall -O3 -lboost_iostreams -o тест main.cpp):Как использовать boost :: iostreams :: mapped_file_source с вложенным файлом gzipped

#include <iostream> 
#include <string> 
#include <boost/iostreams/device/mapped_file.hpp> 

int main() { 
    boost::iostreams::mapped_file_source f_read; 
    f_read.open("in.txt"); 

    long long int alignment_offset(0); 

    // set the start point 
    const char* pt_current(f_read.data() + alignment_offset); 
    // set the end point 
    const char* pt_last(f_read.data() + f_read.size()); 
    const char* pt_current_line_start(pt_current); 

    std::string buffer; 

    while (pt_current && (pt_current != pt_last)) { 
     if ((pt_current = static_cast<const char*>(memchr(pt_current, '\n', pt_last - pt_current)))) { 
      buffer.assign(pt_current_line_start, pt_current - pt_current_line_start + 1); 
      // do something with buffer 

      pt_current++; 
      pt_current_line_start = pt_current; 
     } 
    } 

    return 0; 
} 

в настоящее время, я хотел бы сделать этот код ручки GZIP файлов, а также и изменять код так:

#include<iostream> 
#include<boost/iostreams/device/mapped_file.hpp> 
#include<boost/iostreams/filter/gzip.hpp> 
#include<boost/iostreams/filtering_streambuf.hpp> 
#include<boost/iostreams/filtering_stream.hpp> 
#include<boost/iostreams/stream.hpp> 

int main() { 
    boost::iostreams::stream<boost::iostreams::mapped_file_source> file; 
    file.open(boost::iostreams::mapped_file_source("in.txt.gz")); 

    boost::iostreams::filtering_streambuf<boost::iostreams::input> in; 
    in.push(boost::iostreams::gzip_decompressor()); 
    in.push(file); 

    std::istream std_str(&in); 
    std::string buffer; 
    while(1) { 
     std::getline(std_str, buffer); 
     if (std_str.eof()) break; 
     // do something with buffer 
    } 
} 

Это код также работает хорошо, но я не знаю, как установить начальную точку (pt_current) и конечную точку (pt_ последний), как первый код. Не могли бы вы сообщить мне, как я могу установить два значения во втором коде?

ответ

2

Ответ нет, это невозможно. Сжатый поток должен иметь индексы.


Реальный вопрос: Почему?. Вы используете файл с отображением памяти. Выполнение сжатия/декомпрессии на лету снижает производительность и увеличивает потребление памяти.

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

Двоичное представление может обойти большую часть сложности, связанной с использованием текстовых файлов со случайным доступом.

Некоторых вдохновляющие образцы:


То, что вы в основном обнаружить это, что текстовые файлы не произвольный доступ и сжатие делает индексирование существенно нечетким (нет точного m от сжатия сжатого потока до несжатого смещения потока).

Посмотрите на zran.c, например, в распределении ZLIB как упомянуто в zlib FAQ:

28. Могу ли я получить доступ к данным в случайном порядке в сжатом потоке?

Нет, не без подготовки. Если при сжатии вы периодически используете Z_FULL_FLUSH, аккуратно напишите все ожидающие данные в этих точках и сохраните индекс этих местоположений, после чего вы можете начать декомпрессию в этих точках. Вы должны быть осторожны, чтобы не использовать Z_FULL_FLUSH слишком часто, так как он может значительно ухудшить сжатие. Кроме того, вы можете сканировать поток дефляции один раз для создания индекса, а затем использовать этот индекс для произвольного доступа. См. examples/zran.c

¹ Вы можете конкретно рассмотреть параллельные реализации, такие как, например,pbzip2 или pigz; Они обязательно будут использовать эти «куски» или «рамки», чтобы запланировать нагрузку по ядрам.

+0

Добавлены связанные ответные ссылки, чтобы искривить ваше воображение – sehe

+0

Спасибо, вы спасли мое время. – user4147776