带有 gzip 压缩的 InternetReadFile - 下载并解压缩

问题描述 投票:0回答:1

我正在尝试从服务器下载 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(); 
visual-c++ boost mfc gzip
1个回答
0
投票

您使用

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

© www.soinside.com 2019 - 2024. All rights reserved.