我正在尝试从服务器下载 gzip 文件并使用 Boost 解压缩它。我有一个例外。 _data 值以正确的 gzip 开头(1f 8b 08),但解压缩不起作用。请帮忙。
CInternetSession isession;
CString url = m_url;
std::string _data;
CString hdrs = _T("Accept-Encoding: gzip, deflate\r\nUser-Agent: Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)\r\n");
CHttpFile* httpfile = (CHttpFile*)isession.OpenURL(url, 1, INTERNET_FLAG_SECURE |
INTERNET_FLAG_TRANSFER_BINARY | INTERNET_FLAG_RELOAD, hdrs, hdrs.GetLength());
CString buffer = _T("");
if (httpfile)
{
DWORD dwStatusCode;
httpfile->QueryInfoStatusCode(dwStatusCode);
if (dwStatusCode == 200)
{
DWORD rSize;
char tmp[2048 + 1];
while (InternetReadFile(*httpfile, tmp, 2048, &rSize) && rSize > 0)
{
_data.append(tmp);
tmp[rSize] = '\0';
buffer += (CString)tmp;
}
}
httpfile->Close();
delete httpfile;
}
using namespace boost::iostreams;
filtering_streambuf<input> in;
in.push(gzip_decompressor());
in.push(boost::iostreams::array_source(_data.data(), _data.size()));
std::stringstream _sstream;
boost::iostreams::copy(in, _sstream);///exception here
std::cout << _sstream.rdbuf();
您使用
InternetReadFile
读取的数据是二进制数据,因此 _data.Append(tmp)
没有意义,因为它会认为 tmp
包含以 null 结尾的字符串,因此它只会在 tmp
中附加第一个非空字节。由于您的数据是压缩数据,因此它肯定会包含空字节。因此,如果您使用 _data.Append(tmp, rSize)
代替,它将向 rSize
追加 _data
字节,无论空字节如何,这正是您想要的。
您可能想要这个:
// remove CString buffer;
if (httpfile)
{
DWORD dwStatusCode;
httpfile->QueryInfoStatusCode(dwStatusCode);
if (dwStatusCode == 200)
{
DWORD rSize;
char tmp[2048 + 1];
while (InternetReadFile(*httpfile, tmp, 2048, &rSize) && rSize > 0)
{
_data. Append(tmp, rSize);
}
}
httpfile->Close();
delete httpfile;
}
现在
_data
是包含压缩数据字节的 std::string
,_data::size()
是该数据的总长度。
A
std::string
可以包含空字符,请参阅这个问题:Can a std::string containsEmbedded nulls?,但是您不能在此类字符串上使用 c_str
方法,或者更确切地说,它没有意义.
顺便说一句,您可以写
CString buffer = _T("");
而不是 CString buffer;
,根据定义,它的作用完全相同。但无论如何你都不需要buffer
。