如何從Internet上有效而穩定地下載檔案

來源:互聯網
上載者:User
 

如何從Internet上有效而穩定地下載檔案
作者:hangwire

下載本文來源程式

  如何從Internet上有效而穩定地下載檔案 ,這是很多網路應用程式要考慮的重要問題,本文提供的程式碼片段針對這個問題進行了初步的探索。希望能夠拋磚引玉,對各位編程人員有所協助。

  UINT InternetGetFile (HINTERNET IN hOpen, 
CHAR *szUrl, 
CHAR *szFileName, 
HWND hwndProgress, 
int idStatusText, 
int idProgressBar);

這裡傳回值的類型為UINT,如果成功返回0,否則返回非零值。為了使用這個函數,只需要提供一個有效HINTERNET控制代碼,這個控制代碼可以通過標準的InternetOpen()掉用來獲得。如果你願意的話,你還可以將一個控制代碼提供給進度視窗(ID為一靜態控制的標示符,用來顯示狀態),在這個函數的頭幾行代碼中聲明一些變數。

  DWORD dwSize;
這個變數被用於儲存每次調用InternetReadFile讀取了多少資料。

  CHAR szHead[] = "Accept: */*/r/n/r/n";
用於儲存多個HTTP頭資訊。如果在調用InternetOpenUrl時不傳遞著個頭資訊,則只允許你開啟文字檔!

  VOID* szTemp[16384];
緩衝變數,可以儲存來自Internet的16KB的檔案資料。

  HINTERNET hConnect;
這是一個HINTERNET控制代碼,包含請求結果(來自InternetOpenUrl)

  FILE * pFile;
標準的C檔案控制代碼(必須包含stdio.h)。如果你願意,可以使用Win32處理檔案的API

  if (!(hConnect = InternetOpenUrlA (hOpen, szUrl, szHead, lstrlenA (szHead), INTERNET_FLAG_DONT_CACHE | INTERNET_FLAG_PRAGMA_NOCACHE | INTERNET_FLAG_RELOAD, 0)))
{
return INTERNET_ERROR_OPENURL;
}
  此調用可以開啟一個使用URL的Internet檔案控制代碼。標誌表示這個檔案總是被讀取,而不是緩衝(cache)。如果失敗,則此函數返回錯誤,你可以給定INTERNET_ERROR_OPENURL任何值。必須為這個函數定義所有的錯誤資訊。也可以用一個數字替代。

  if(!(pFile = fopen(szFileName, "wb" )))
{
return INTERNET_ERROR_FILEOPEN;
}
此調用根據給定的檔案名稱開啟檔案。如果失敗則返回另一個使用者定義的錯誤。

  DWORD dwByteToRead = 0;
DWORD dwSizeOfRq = 4;
DWORD dwBytes = 0;
這三個值分別隱藏檔的大小,HttpQueryInfo內容的大小和總共讀取的位元組數。

  if (!HttpQueryInfo(hConnect, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, (LPVOID)&dwByteToRead, &dwSizeOfRq, NULL))
{
dwByteToRead = 0;
}
此調用可以獲得檔案的大小。如果失敗則dwByteToRead被置為0,並且當檔案被下載時不會顯示百分比和總數

  DWORD start;
DWORD end;
DWORD time;
time = 10;
start = timeGetTime();
使用這些bit必須包含mmsystem.h並連結winmm.lib,它們用於時間選擇,告訴使用者下載的速度。例子代碼只統計了下載速度,你可以擴充這個功能,比如估計還剩多少時間。

  do
{
if (!InternetReadFile(hConnect, szTemp, 16384, &dwSize))
{
fclose (pFile);
return INTERNET_ERROR_READFILE;
}
此調用迴圈中,每次下載一個16KB的資料區塊。如果download請求失敗,則檔案被關閉並返回錯誤。

  if (!dwSize)
break;
else
fwrite(szTemp, sizeof(char), dwSize, pFile);
如果dwSize為0,則意味著一個EOF,迴圈退出。否則由InternetReadFile讀取的資料內容被寫到本地檔案中。

  dwBytes+=dwSize;
if(dwByteToRead && hwndProgress)
{
SendDlgItemMessageA(hwndProgress, idProgressBar, WM_USER+2, (dwBytes*100)/dwByteToRead, 0);
UpdateWindow(hwndProgress);
}
這個代碼中,dwBytes是從檔案讀取的資料量,它不斷增加,如果檔案長度是有效,則進度視窗控制代碼被指定,進度條被更新已表示下載進度。

  FLOAT fSpeed = 0;
fSpeed = (float)dwBytes;
fSpeed /= ((float)time)/1000.0f;
fSpeed /= 1024.0f;
這些bit代碼用於根據所花時間計算下載速度和讀取的資料量。

  if(hwndProgress)
{
char s[260];
sprintf(s, "%d KB / %d KB @ %1.1f KB/s", dwBytes/1024, dwByteToRead/1024, fSpeed);
SetDlgItemTextA(hwndProgress, idStatusText, s);
UpdateWindow(hwndProgress);
}
設定和處理進度視窗的狀態文本,表示下載的檔案大小和下載速度。

  end = timeGetTime();
time = end - start;
if(time == 0)
time = 10;

時間被更新

} // do
while (TRUE);

迴圈結束
fflush (pFile);
fclose (pFile);
return 0;
}
最後,函數結束,關閉檔案並清除硬體驅動的緩衝。返回0表示成功。

  使用這個程式碼片段,按照本文所描述的那樣,你可以自己編寫一個程式來從Internet上有效地、穩定地下載檔案。實現細節請參見例子。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.