網路下載檔案小程式(非原創,他人所寫)
阿新 • • 發佈:2019-01-01
#include <Windows.h> #include <iostream> #include <string> #include <vector> #include <algorithm> #include <wininet.h> #include <shellApi.h> #include <Shlwapi.h> #include <ShlObj.h> #define INVALID_FILE_ATTRIBUTES ((DWORD)-1) #pragma comment(lib, "shlwapi.lib") #pragma comment(lib,"wininet") using namespace std; bool DownloadFile(LPCTSTR szUrl,LPCTSTR szLocalFile,BOOL bFailIfExists); int main(int argc, char* argv[]) { std::cout<<DownloadFile("http://www.baidu.com/","d:\\1.htm",TRUE)<<std::endl; getchar(); return 0; } bool DownloadFile(LPCTSTR szUrl,LPCTSTR szLocalFile,BOOL bFailIfExists) { if (bFailIfExists && !PathIsDirectory(szLocalFile) && (GetFileAttributes(szLocalFile) != INVALID_FILE_ATTRIBUTES)) { return false; } HANDLE hFile = INVALID_HANDLE_VALUE; HINTERNET hInet = NULL; HINTERNET hUrl = NULL; DWORD dwBuf = 1024*1024,dwRead = 0; //1M auto_ptr<char> szBuf(new char[dwBuf]); memset(szBuf.get(),0,dwBuf); std::string strTmp; bool bRet = false; try { hFile = CreateFile(szLocalFile,GENERIC_READ|GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); if (hFile == INVALID_HANDLE_VALUE) throw "error"; hInet = InternetOpen(NULL,INTERNET_OPEN_TYPE_PRECONFIG,NULL,NULL,0); if (hInet == NULL) throw "error"; hUrl = InternetOpenUrl(hInet,szUrl,NULL,0, INTERNET_FLAG_TRANSFER_BINARY|INTERNET_FLAG_NO_CACHE_WRITE|INTERNET_FLAG_RELOAD,0); if (hUrl == NULL) throw "error"; for(;;) { if (!InternetReadFile(hUrl,szBuf.get(),dwBuf,&dwRead)) { bRet = false; break; } if (dwRead == 0) { bRet = true; break; } //strTmp += std::string(szBuf,dwRead); WriteFile(hFile,szBuf.get(),dwRead,&dwRead,NULL); } throw "ok"; } catch(...) { if (hFile != INVALID_HANDLE_VALUE) CloseHandle(hFile); if (hUrl != NULL) InternetCloseHandle(hUrl); if (hInet != NULL) InternetCloseHandle(hInet); } return bRet; }
InternetReadFile函式
InternetReadFile Function
SyntaxC++BOOL InternetReadFile( __in HINTERNET hFile, __out LPVOID lpBuffer, __in DWORD dwNumberOfBytesToRead, __out LPDWORD lpdwNumberOfBytesRead);Parameters
hFile [in]
lpBuffer [out]
緩衝器指標
dwNumberOfBytesToRead [in]
欲讀資料的位元組量。
lpdwNumberOfBytesRead
[out]接收讀取位元組量的變數。該函式在做任何工作或錯誤檢查之前都設定該值為零
返回值
成功:返回TRUE,失敗,返回FALSE
備註
該函式的操作非常類似於ReadFile函式。典型情況下,該函式從一個作為位元組順序流的HINTERNET控制代碼中返回資料。每次函式讀取的資料量都由dwNumberOfBytesToRead引數指定,並且資料返回到lp Buffer引數裡。一個正常讀取將持續到檔案結束時為止。為了確保所有資料被接收,應用程式必須繼續使用該函式直到函式返回TRUE且lpdwNumberOfBytesRead引數等於零值。此舉在請求的資料被寫入快取中尤為重要,因為如不這樣的話,快取將不會正常的更新且下載的檔案也將不會被允許寫入到快取中。注意:除了原始請求的命令設定為INTERNET_FLAG_NO_CACHE_WRITE標識的情況外,快取操作都會自動進行。當應用程式使用
InternetOpenUrl函式獲得一個控制代碼時,WinINet試圖將所有的資料都變得如同檔案下載一樣。WinINet試圖每次向lpBuffer緩衝中寫入一行HTML。如果應用程式的緩衝區太小以至於不能承載一行的HTML資料,錯誤程式碼ERROR_INSUFFICIENT_BUFFER 將傳送給應用程式,通知它需要更大的緩衝區。同樣,轉換的行數也不一定和緩衝區的大小匹配,所以該函式可以返回比lpBuffer緩衝少的資料。接下來的讀取工作將返回所有的HTML資料。應用程式必須再次檢查搜有資料是否都被接收。
(InternetReadFile函式說明轉自:http://hi.baidu.com/fangenhong/item/5b11fd91777e6f1b924f41e4)