может записать файл с помощью zlib, но не может прочитать его обратно - PullRequest
0 голосов
/ 31 марта 2020

Я хочу иметь возможность хранить данные в data.bin.gz using, используя zstr (библиотека, которая использует zlib). Мне удалось записать в файл, но я не могу прочитать его обратно. Вот краткий пример.

std::auto_ptr<std::ostream> ofs = std::auto_ptr<std::ostream>(new zstr::ofstream(fileName));

std::string str("hello world");
ofs.get()->write(str.c_str(), 11);
std::cout << "data sent: " << str << std::endl;

std::auto_ptr<std::istream> ifs = std::auto_ptr<std::istream>(new zstr::ifstream(fileName));

std::streamsize buffSize = 11;
char* buff = new char [11];
// fill buff to see if its content change
for (int i = 0; i < 11; i++) {
    buff[i] = 'A';
}

ifs.get()->read(buff, buffSize);
std::cout << std::string(buff, buff+11) << std::endl;

delete [] buff;

Я заполняю бафф некоторым контентом specfi c, чтобы посмотреть, не изменится ли он при чтении потока. но это не изменится.

1 Ответ

1 голос
/ 31 марта 2020

Вот версия, которая делает примерно то, что вам нужно, но использует стандартные файловые потоки, а не нестандартную библиотеку zstr, которая здесь не кажется существенной:

#include <iostream>
#include <fstream>
#include <memory>
#include <string>
#include <vector>

using namespace std::string_literals;

int main()
{
    constexpr auto fileName = "test.bin";

    {
        const auto str = "hello world"s;
        auto       ofs = std::ofstream( fileName, std::ios::binary );
        ofs.write( str.data(), str.size() );
    } // ofs is closed here by RAII

    auto buff = std::vector<char>(100, 'A');
    auto ifs  = std::ifstream( fileName, std::ios::binary );
    ifs.read(buff.data(), buff.size());
    std::cout << std::string(buff.data(), buff.data()+11) << '\n';
}

Она выводит hello world как и ожидалось. Смотрите его в прямом эфире на Coliru .

Примечания:

  1. Я удалил auto_ptr и добавил правильную область видимости.
  2. Я не управляю памятью вручную (new / delete), что является плохой формой. Вместо этого я использую std::vector и std::string.
  3. Я добавил флаг std::ios::binary к конструкторам fstream, чтобы открывать их в двоичном режиме, так как это то, что, по-видимому, вы в конечном итоге хотите сделать. Это может не понадобиться для используемой вами библиотеки zstr.
  4. Я увеличил буфер, как будто я не знаю, что находится в файле. Затем я прочитал из него столько места, сколько выделил. При печати результата я использую «инсайдерские знания», что существует 11 действительных байтов. Альтернативой было бы инициализировать вектор для всех нулей (по умолчанию) и просто напечатать его в виде строки:
    auto buff = std::vector<char>( 100 );
    auto ifs  = std::ifstream( fileName, std::ios::binary );
    ifs.read(buff.data(), buff.size() - 1); // Keep one zero for null terminator
    std::cout << buff.data() << '\n';

, которую вы также можете увидеть вживую на Coliru .

Я также модернизировался несколькими другими способами просто для забавы и в образовательных целях:

  1. Я использую constexpr для константы, известной во время компиляции.
  2. Я использую строковый литерал s в str для создания std::string с большей краткостью.
  3. Я использую стиль ' почти всегда автоматически ' для объявлять объекты.
  4. Использовать \n вместо std::endl, потому что вам не нужен дополнительный грипп sh (хорошая привычка быть).
...