Как заставить boost :: iostream работать в режиме, сравнимом с std :: ios :: binary? - PullRequest
4 голосов
/ 28 июня 2010

У меня следующий вопрос по boost::iostreams. Если кто-то знаком с написанием фильтров, я буду признателен за ваши советы / помощь.

Я пишу пару многоканальных фильтров, которые работают с boost::iostream::filtering_stream как компрессор данных и декомпрессор. Я начал с написания компрессора, взял некоторый алгоритм из семейства lz и сейчас работаю над декомпрессором.

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

Когда мне нужно восстановить данные из моего файла (в терминах программирования, получить запрос read(byte_count)), я должен прочитать полный упакованный блок, буферизировать его, распаковать и только потом дать запрошенное количество байтов. Я реализовал эту логику, но сейчас я борюсь с следующей проблемой:


Когда мои данные упакованы, в выходном файле могут появиться любые символы. И у меня возникают проблемы при чтении файла, который содержит символ (hex 1A, char 26), используя boost::iostreams::read(...., size).

Например, если бы я использовал std::ifstream, я бы установил режим std::ios::binary, и тогда этот символ можно было бы просто прочитать.

Любой способ добиться того же при реализации фильтра boost::iostream, который использует подпрограмму boost::iostream::read для чтения последовательности символов?


Код здесь:

   // Compression
   // -----------
   filtering_ostream out;
   out.push(my_compressor());
   out.push(file_sink("file.out"));

   // Compress the 'file.in' to 'file.out'
   std::ifstream stream("file.in");
   out << stream.rdbuf();


   // Decompression
   // -------------
   filtering_istream in;
   in.push(my_decompressor());
   in.push(file_source("file.out"));

   std::string res;
   while (in) {
      std::string t;

      // My decompressor wants to retrieve the full block from input (say, 4096 bytes)
      // but instead retrieves 150 bytes because meets '1A' char in the char sequence

      // That obviously happens because file should be read as a binary one, but
      // how do I state that?
      std::getline(in, t); // <--------- The error happens here

      res += t;
   }

1 Ответ

1 голос
/ 28 июня 2010

Краткий ответ для чтения файла в двоичном виде:

указать ios_base::binary при открытии файлового потока.

MSDN Link

...