首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> 關於VC++

網路檔案下載:InternetReadFile 分塊讀取、進度條、速度顯示完整實作

     編輯:關於VC++

核心函數原型

UINT InternetGetFile(HINTERNET hOpen, LPCSTR szUrl, LPCSTR szFileName,
    HWND hProgressDlg, int idStatusText, int idProgressBar);

關鍵實作細節

// 1. 開啟 URL(禁用快取,強制重新下載)
HINTERNET hConnect = InternetOpenUrlA(hOpen, szUrl,
    "Accept: */*\r\n\r\n", -1,
    INTERNET_FLAG_DONT_CACHE | INTERNET_FLAG_PRAGMA_NOCACHE | INTERNET_FLAG_RELOAD,
    0);

// 2. 開啟本地檔案(二進位寫入)
FILE* fp = fopen(szFileName, "wb");

// 3. 取得檔案總大小(用於進度條)
DWORD fileSize = 0, sizeLen = 4;
HttpQueryInfo(hConnect, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER,
    &fileSize, &sizeLen, nullptr);

// 4. 分塊下載迴圈(16KB 緩衝區)
BYTE buffer[16384];
DWORD totalRead = 0, readSize;
DWORD startTime = timeGetTime();

do {
    if (!InternetReadFile(hConnect, buffer, 16384, &readSize)) break;
    if (readSize == 0) break; // EOF

    fwrite(buffer, 1, readSize, fp);
    totalRead += readSize;

    // 更新進度條
    if (fileSize && hProgressDlg) {
        int percent = (totalRead * 100) / fileSize;
        SendDlgItemMessage(hProgressDlg, idProgressBar, WM_USER+2, percent, 0);
    }

    // 計算並顯示下載速度
    DWORD elapsed = timeGetTime() - startTime;
    if (elapsed == 0) elapsed = 1;
    float speedKB = (totalRead / 1024.0f) / (elapsed / 1000.0f);
    char status[260];
    sprintf(status, "%d KB / %d KB @ %.1f KB/s",
        totalRead/1024, fileSize/1024, speedKB);
    SetDlgItemText(hProgressDlg, idStatusText, status);

} while (true);

fclose(fp);
return 0;

必要連結庫

  • wininet.lib:Internet API
  • winmm.lib:timeGetTime 計算速度

健壯性建議

  • 支援斷點續傳:記錄 totalRead,下次以 Range 標頭續傳
  • 異常處理:網路中斷、磁碟滿、伺服器錯誤碼檢查
  • 大檔案:使用 64 位元位移與 InternetSetFilePointer
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved