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 << "%\t" << ulStatusCode << "\n"; 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 << "\t" << size << "\t" << mSize << "\n"; 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!\n"; 148 } 149152 153 delete listener; 154 155 system("pause"); 156 }