c++下利用URLOpenStream下载

URLDownloadToFile实现文件下载很方便

#include <Urlmon.h>
#pragma comment(lib, "urlmon.lib")

bool downloadFile(const char* url, const char* fileName)
{
	HRESULT res = URLDownloadToFileA(NULL, url, fileName, 0, NULL);
	 
	return (res == S_OK);
}

但你可能想利用URLOpenStream实现更复杂的需求(比如不保存磁盘文件)

但查msdn还是比较麻烦的,这里直接上示例代码:

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <UrlMon.h>
  4 #pragma comment(lib, "urlmon.lib")
  5 #include <tchar.h>
  6 #include <fstream>
  7 
  8 class MyListener : public IBindStatusCallback
  9 {
 10 public:
 11 
 12     STDMETHOD(OnStartBinding)(
 13         DWORD dwReserved,
 14         IBinding __RPC_FAR *pib)
 15     {
 16         return E_NOTIMPL;
 17     }
 18 
 19     STDMETHOD(GetPriority)(
 20         LONG __RPC_FAR *pnPriority)
 21     {
 22         return E_NOTIMPL;
 23     }
 24 
 25     STDMETHOD(OnLowResource)(
 26         DWORD reserved)
 27     {
 28         return E_NOTIMPL;
 29     }
 30 
 31     STDMETHOD(OnProgress)(
 32         ULONG ulProgress,    //当前大小
 33         ULONG ulProgressMax, //总大小
 34         ULONG ulStatusCode,
 35         LPCWSTR szStatusText)
 36     {
 37         if (ulProgressMax != 0)
 38         {
 39             std::cout << ulProgress * 100.0 / ulProgressMax << "%	" << ulStatusCode << "
";
 40         }
 41         return S_OK;
 42     }
 43 
 44     STDMETHOD(OnStopBinding)(
 45         HRESULT hresult,
 46         LPCWSTR szError)
 47     {
 48         return E_NOTIMPL;
 49     }
 50 
 51     STDMETHOD(GetBindInfo)(
 52         DWORD __RPC_FAR *grfBINDF,
 53         BINDINFO __RPC_FAR *pbindinfo)
 54     {
 55         return E_NOTIMPL;
 56     }
 57 
 58     STDMETHOD(OnDataAvailable)(
 59         DWORD grfBSCF,
 60         DWORD dwSize,
 61         FORMATETC __RPC_FAR *pformatetc,
 62         STGMEDIUM __RPC_FAR *pstgmed)
 63     {
 64             //BSCF_FIRSTDATANOTIFICATION = 0x00000001,
 65             //BSCF_INTERMEDIATEDATANOTIFICATION = 0x00000002,
 66             //BSCF_LASTDATANOTIFICATION = 0x00000004,
 67         //有可能为BSCF_FIRSTDATANOTIFICATION, BSCF_FIRSTDATANOTIFICATION & BSCF_LASTDATANOTIFICATION, BSCF_INTERMEDIATEDATANOTIFICATION, BSCF_LASTDATANOTIFICATION
 68         //即可能为一个包、两个包或多个包
 69         if (grfBSCF & BSCF_FIRSTDATANOTIFICATION) 
 70         {
 71             pstgmed->pstm->Read(mData, dwSize, &mSize);
 72         }
 73         else
 74         {
 75             ULONG size;
 76             pstgmed->pstm->Read(mData + mSize, dwSize, &size);
 77             mSize += size;
 78             std::cout << dwSize << "	" << size << "	" << mSize << "
";
 79         }
 80 
 81         
 82         return S_OK;
 83     }
 84 
 85     STDMETHOD(OnObjectAvailable)(
 86         REFIID riid,
 87         IUnknown __RPC_FAR *punk)
 88     {
 89         return E_NOTIMPL;
 90     }
 91 
 92     STDMETHOD_(ULONG, AddRef)()
 93     {
 94         return 0;
 95     }
 96 
 97     STDMETHOD_(ULONG, Release)()
 98     {
 99         return 0;
100     }
101 
102     STDMETHOD(QueryInterface)(
103         REFIID riid,
104         void __RPC_FAR *__RPC_FAR *ppvObject)
105     {
106         return E_NOTIMPL;
107     }
108 
109     void save(char* fileName)
110     {
111         file.open(fileName, std::ios::binary);
112         file.write(mData, mSize);
113         file.close();
114     }
115 private:
116     std::ofstream file;
117     ULONG mSize;
118     char mData[64 * 1024];
119 };
120 
121 
122 int main(int argc, char* argv[])
123 {
124     char url[256];
125     char fileName[256];
127 
128     MyListener* listener = new MyListener;
140     HRESULT result = URLOpenStream(0, url, 0, listener);
141             if (result == S_OK)
142             {
143                 listener->save(fileName);
144             }
145             else
146             {
147                 std::cout << result << "    failure!
";
148             }
149152 
153     delete listener;
154 
155     system("pause");
156 }

原文地址:https://www.cnblogs.com/wiki3d/p/download.html