UrlDownloadToFile到内存

时间:2017-05-17 14:29:30

标签: c++ wininet

我使用URLDownloadToFile()将图片从网络服务器下载到桌面上的目录。如果我不是将图像保存到磁盘,而是想将它们读入内存(如字节数组或base64字符串之类的东西),是否有类似于URLDownloadToFile()的函数可以实现这一点?

2 个答案:

答案 0 :(得分:1)

Win32 API中没有单个执行所有功能,可以将URL资源下载到内存中,就像URLDownloadToFile()对文件一样。您必须编写自己的请求URL的函数,然后将数据读入内存。

例如,使用InternetOpenUrl()HttpOpenRequest() / HttpSendRequest(),然后使用InternetReadFile()。有关详细信息,请参阅MSDN上的Downloading Resources from the WWW

或使用您选择的任何其他HTTP / S库/ API。

答案 1 :(得分:1)

URLOpenStream()URLOpenBlockingStream()URLOpenPullStream()可让您下载到内存中。

从这三个中,URLOpenBlockingStream()似乎是最直接的,因为它返回一个IStream指针,您可以从中循环同步读取。虽然它不像URLDownloadToFile()这样的 do-all 功能,但使用起来并不困难。

以下是URLOpenBlockingStream()的完整示例控制台应用程序。它从URL下载并将响应写入stdout。而不是这样,您可以将响应存储在std::vector中,或者随意做任何事情。

#include <Windows.h>
#include <Urlmon.h>   // URLOpenBlockingStreamW()
#include <atlbase.h>  // CComPtr
#include <iostream>
#pragma comment( lib, "Urlmon.lib" )

struct ComInit
{
    HRESULT hr;
    ComInit() : hr( ::CoInitialize( nullptr ) ) {}
    ~ComInit() { if( SUCCEEDED( hr ) ) ::CoUninitialize(); } 
};

int main(int argc, char* argv[])
{
    ComInit init;

    // use CComPtr so you don't have to manually call Release()
    CComPtr<IStream> pStream;  

    // Open the HTTP request.
    HRESULT hr = URLOpenBlockingStreamW( nullptr, L"http://httpbin.org/headers", &pStream, 0, nullptr );
    if( FAILED( hr ) )
    {
        std::cout << "ERROR: Could not connect. HRESULT: 0x" << std::hex << hr << std::dec << "\n"; 
        return 1;
    }

    // Download the response and write it to stdout.
    char buffer[ 4096 ];
    do
    {
        DWORD bytesRead = 0;
        hr = pStream->Read( buffer, sizeof(buffer), &bytesRead );

        if( bytesRead > 0 )
        {
            std::cout.write( buffer, bytesRead );
        }
    } 
    while( SUCCEEDED( hr ) && hr != S_FALSE );

    if( FAILED( hr ) )
    {
        std::cout << "ERROR: Download failed. HRESULT: 0x" << std::hex << hr << std::dec << "\n";
        return 2;
    }

    std::cout << "\n";

    return 0;
}