C++ URL下载文件到内存
我正在使用URLDownloadToFile将图像从web服务器下载到桌面上的一个目录中。如果我不想将图像保存到磁盘,而是想将它们像字节数组或base64字符串之类读入内存,那么有没有类似于URLDownloadToFile的函数可以实现这一点?Win32 API中没有像URLDownloadToFile那样为文件下载URL资源到内存中的单个do all函数。您必须编写自己的函数来请求URL,然后将数据读入内存 例如,使用或/,然后。有关更多详细信息,请参阅MSDN上的 或者使用您选择的任何其他HTTP/S库/API。有,允许您下载到内存中 从这三个方面来看,它似乎是最容易使用的,因为它返回一个IStream指针,您可以在循环中同步读取该指针。虽然它不像URLDowloadToFile那样是一个单一的全能函数,但使用起来并不困难 下面是一个完整的控制台应用程序示例。它从URL下载并将响应写入标准输出。与此相反,您可以将响应存储在std::vector中,或者对其执行任何您喜欢的操作C++ URL下载文件到内存,c++,wininet,C++,Wininet,我正在使用URLDownloadToFile将图像从web服务器下载到桌面上的一个目录中。如果我不想将图像保存到磁盘,而是想将它们像字节数组或base64字符串之类读入内存,那么有没有类似于URLDownloadToFile的函数可以实现这一点?Win32 API中没有像URLDownloadToFile那样为文件下载URL资源到内存中的单个do all函数。您必须编写自己的函数来请求URL,然后将数据读入内存 例如,使用或/,然后。有关更多详细信息,请参阅MSDN上的 或者使用您选择的任何其他
#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;
}
“错了,请看我的答案。@zett42:但这并不是一个完全类似于URLDownloadToFile的函数。”。您必须首先打开一个流,然后从该流中读取。这些都是单独的操作,因此与我的回答没有什么不同,只是使用了不同的API。请注意,我说过没有像URLDownloadToFile…这样的“全部完成”函数,这是真的。全部完成的函数应该是URLOpenStream,我刚刚选择URLOpenBlockingStream作为更简单的示例。@zett42:URLOpenStream几乎不是一个“全部完成”函数,因为它需要调用方传入一个单独的IBindStatusCallback对象来处理OnDataAvailable回调,并且数据是以STDMEDIUM格式提供的,这需要额外的函数调用来提取数据,因为它可以是HGLOBAL、IStream或IStorage格式。do all函数是这样一个函数,其中调用者只需传入URL和内存块或输出流,并且该函数完全填充输出,而不需要调用者做任何工作。没有一个Win32 API函数可以做到这一点。我明白这一点。