可以用 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.
上观看直播
备注:
- 我删除了
auto_ptr
并添加了适当的范围。
- 我不手动管理内存 (
new
/delete
),这是错误的形式。相反,我使用 std::vector
和 std::string
。
- 我将
std::ios::binary
标志添加到 fstream
构造函数中以二进制模式打开,因为这似乎是您最终想要做的。您正在使用的 zstr 库可能不需要它。
- 我把缓冲区变大了,好像我不知道文件里有什么。然后我从中读取了我分配的 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.
上看到直播
出于娱乐和教育目的,我还通过其他一些方式进行了现代化改造:
- 我在编译时已知的常量上使用
constexpr
。
- 我在
str
上使用字符串文字后缀 s
来创建更简洁的 std::string
。
- 我使用“almost always auto”样式来声明对象。
- 使用
\n
而不是std::endl
因为you don't need the extra flush(要养成的好习惯)。
我希望能够使用 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.
备注:
- 我删除了
auto_ptr
并添加了适当的范围。 - 我不手动管理内存 (
new
/delete
),这是错误的形式。相反,我使用std::vector
和std::string
。 - 我将
std::ios::binary
标志添加到fstream
构造函数中以二进制模式打开,因为这似乎是您最终想要做的。您正在使用的 zstr 库可能不需要它。 - 我把缓冲区变大了,好像我不知道文件里有什么。然后我从中读取了我分配的 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.
上看到直播出于娱乐和教育目的,我还通过其他一些方式进行了现代化改造:
- 我在编译时已知的常量上使用
constexpr
。 - 我在
str
上使用字符串文字后缀s
来创建更简洁的std::string
。 - 我使用“almost always auto”样式来声明对象。
- 使用
\n
而不是std::endl
因为you don't need the extra flush(要养成的好习惯)。