C++ C++;文件中字符串的zlib压缩

C++ C++;文件中字符串的zlib压缩,c++,string,file,compression,zlib,C++,String,File,Compression,Zlib,我一直在尝试压缩字符串并将其保存到文本文件中,然后读取数据并解压缩。但是,当我尝试解压缩读取的字符串时,会出现Z_BUF_错误(-5),并且该字符串可能会解压缩,也可能不会解压缩 在控制台中,我可以整天压缩/解压缩: std::string s = zlib_compress("HELLO asdfasdf asdf asdfasd f asd f asd f awefo@8 892y*(@Y"); std::string e = zlib_decompress(s); 字符串e将毫不费力地返

我一直在尝试压缩字符串并将其保存到文本文件中,然后读取数据并解压缩。但是,当我尝试解压缩读取的字符串时,会出现Z_BUF_错误(-5),并且该字符串可能会解压缩,也可能不会解压缩

在控制台中,我可以整天压缩/解压缩:

std::string s = zlib_compress("HELLO asdfasdf asdf asdfasd f asd f asd f awefo@8 892y*(@Y");
std::string e = zlib_decompress(s);
字符串
e
将毫不费力地返回原始字符串

但是,当我这样做时:

zlib_解压(readFile(filename))

我得到一个
Z\u BUF\u错误
。我想部分原因可能是文件中隐藏的字符,但我不确定

这是我的
readFile
函数:

std::string readFile(std::string filename)
{
    std::ifstream file;
    file.open(filename.c_str(), std::ios::binary);

    file.seekg (0, std::ios::end);
    int length = file.tellg();
    file.seekg (0, std::ios::beg);

    char * buffer = new char[length];

    file.read(buffer, length);
    file.close();

    std::string data(buffer);

    return data;
}
当我写入压缩数据时,我使用:

void writeFile(std::string filename, std::string data)
{
    std::ofstream file;
    file.open(filename.c_str(), std::ios::binary);
    file << data;
    file.close();
}
void writeFile(std::string文件名,std::string数据)
{
流文件的std::of;
file.open(filename.c_str(),std::ios::binary);

文件由于文件可能包含
'\0'
字符,因此在将内容分配给
std::string
时,应指定大小

std::string data(buffer, length);

由于文件可能包含
'\0'
字符,因此在将内容分配给
std::string
时,应指定大小

std::string data(buffer, length);

首先,您要处理的二进制数据可能包含也可能不包含嵌入的空字符。
std::string
实际上并不是正确的容器,尽管如果正确地处理嵌入的空字符,您可以处理它。但是,使用
std::string
来存储某些文档时,您会被打破取消该公约

第二,行
std::string数据(缓冲区)这是你应该用来构造一个空终止的C字符串的一个构造函数。你在这里处理二进制数据,所以有一个机会,你要么没有得到完整的缓冲区到字符串中,因为它遇到缓冲区中间的一个空终止符,或者运行它。f缓冲区结束,直到它找到空值(或seg错误)。如果绝对肯定必须使用std::string,请使用“正确”构造函数,即
std::string数据(缓冲区,长度);


总之,您使用了错误的数据结构-您需要的是字符/无符号字符的动态数组。这将是一个
std::vector
,而不是
std::string
。另外,您还应该通过常量引用将参数传递到
readFile
writeFile
,您编写的代码将生成副本如果您将缓冲区传递到
writeFile()中
很大,这将导致内存消耗和性能受到不愉快的影响,而且完全没有必要。

首先,您处理的是可能包含或可能不包含嵌入空字符的二进制数据。
std::string
实际上不是正确的容器,尽管您可以在以下情况下处理嵌入的空字符:但是,使用
std::string
来存储某个特定期望的文档,您正在打破这个惯例

第二,行
std::string数据(缓冲区)这是你应该用来构造一个空终止的C字符串的一个构造函数。你在这里处理二进制数据,所以有一个机会,你要么没有得到完整的缓冲区到字符串中,因为它遇到缓冲区中间的一个空终止符,或者运行它。f缓冲区结束,直到它找到空值(或seg错误)。如果绝对肯定必须使用std::string,请使用“正确”构造函数,即
std::string数据(缓冲区,长度);


总之,您使用了错误的数据结构-您需要的是字符/无符号字符的动态数组。这将是一个
std::vector
,而不是
std::string
。另外,您还应该通过常量引用将参数传递到
readFile
writeFile
,您编写的代码将生成副本如果传递到
writeFile()
的缓冲区很大,则会对内存消耗和性能造成不愉快的影响,而且这完全是不必要的。

关于它的价值,下面介绍如何更改
readFile()
writeFile()

std::vector readFile(const std::string和filename)
{
std::ifstream文件;
file.open(filename.c_str(),std::ios::binary);
file.seekg(0,std::ios::end);
const int length=file.tellg();
file.seekg(0,std::ios::beg);
std::矢量数据(长度);
读取(数据[0],长度(&D));
file.close();
返回数据;
}
void writeFile(const std::string和filename,const std::vector和data)
{
流文件的std::of;
file.open(filename.c_str(),std::ios::binary);
file.write(&data[0],data.size());
file.close();
}

然后,您还可以将
compress()
decompress()
函数更改为使用
std::vector
。还要注意,到目前为止,代码缺少任何错误处理。例如,如果文件不存在,会发生什么情况?调用
file.open()
后,您可以通过执行
if(!file)来检查任何错误{/*错误处理*/}

为了实现它的价值,下面介绍如何更改
readFile()
writeFile()

std::vector readFile(const std::string和filename)
{
std::ifstream文件;
file.open(filename.c_str(),std::ios::binary);
file.seekg(0,std::ios::end);
const int length=file.tellg();
file.seekg(0,std::ios::beg);
std::矢量数据(长度);
读取(数据[0],长度(&D));
file.close();
返回数据;
}
void writeFile(const std::string和filename,const std::vector和data)
{
流文件的std::of;
file.open(filename.c_str(),std::ios::binary);
file.write(&data[0],data.size());
file.close();
}
然后你也会改变你的想法<