可以用 zlib 写文件但不能读回

can write file with zlib but cannot read it back

我希望能够使用 zstr(一个使用 zlib 的库)将数据存储到 data.bin.gz using 中。我成功写入文件,但无法读回。这是一个简短的例子。

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;

我用一些特定的内容填充 buff 以查看它在读取流时是否发生变化。但它没有改变。

这是一个大致满足您要求的版本,但使用标准文件流,而不是非标准 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::vectorstd::string
  3. 我将 std::ios::binary 标志添加到 fstream 构造函数中以二进制模式打开,因为这似乎是您最终想要做的。您正在使用的 zstr 库可能不需要它。
  4. 我把缓冲区变大了,好像我不知道文件里有什么。然后我从中读取了我分配的 space 。打印结果时,我使用 "insider knowledge" 表示有 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. 我在 str 上使用字符串文字后缀 s 来创建更简洁的 std::string
  3. 我使用“almost always auto”样式来声明对象。
  4. 使用\n而不是std::endl因为you don't need the extra flush(要养成的好习惯)。