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

C# 從網路下載圖片並儲存至指定路徑完整實作教學

     編輯:關於C語言

前言

在 C# 開發中,從網路上抓取圖片並儲存到本地端是常見需求。本文提供一個完整、健壯的靜態方法 SaveImageFromWeb,支援 URL 驗證、副檔名自動偵測、HTTP 標頭偽裝、串流分塊寫入與資源正確釋放,適合直接納入專案工具庫。

核心程式碼

public static int SaveImageFromWeb(string imgUrl, string path, string fileName)
{
    // 1. 參數檢查
    if (string.IsNullOrWhiteSpace(path))
        throw new ArgumentException("未指定儲存路徑", nameof(path));

    // 2. 從 URL 解析檔名與副檔名
    string imgName = Path.GetFileName(new Uri(imgUrl).LocalPath);
    string imgExt = Path.GetExtension(imgName).ToLowerInvariant();
    string[] validExts = { ".jpg", ".jpeg", ".png", ".gif", ".bmp" };
    if (!validExts.Contains(imgExt))
        imgExt = ".jpg"; // 預設回落

    // 3. 建立 HTTP 請求(模擬瀏覽器 User-Agent、設定逾時)
    var request = (HttpWebRequest)WebRequest.Create(imgUrl);
    request.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36";
    request.Timeout = 10000; // 10 秒

    // 4. 取得回應並驗證 Content-Type
    using (var response = (HttpWebResponse)request.GetResponse())
    {
        if (!response.ContentType.StartsWith("image/", StringComparison.OrdinalIgnoreCase))
            return 0; // 非圖片內容

        // 5. 決定最終檔名
        if (string.IsNullOrWhiteSpace(fileName))
            fileName = Path.GetFileNameWithoutExtension(imgName);
        string fullPath = Path.Combine(path, fileName + imgExt);

        // 6. 串流分塊寫入(避免大檔案佔用過多記憶體)
        using (var responseStream = response.GetResponseStream())
        using (var fileStream = new FileStream(fullPath, FileMode.Create, FileAccess.Write, FileShare.None))
        {
            byte[] buffer = new byte[8192];
            int bytesRead;
            while ((bytesRead = responseStream.Read(buffer, 0, buffer.Length)) > 0)
                fileStream.Write(buffer, 0, bytesRead);
        }
    }
    return 1; // 成功
}

關鍵設計重點解析

1. 安全的路徑與檔名處理

使用 Path.GetFileName、Path.Combine 避免路徑穿越攻擊;副檔名採用白名單機制,防止惡意副檔名上傳。

2. HTTP 請求優化

  • User-Agent 偽裝:避免部分網站封鎖預設 WebRequest 的請求。
  • Timeout 設定:預設 10 秒,防止網路卡住導致執行緒永久阻塞。

3. 串流處理最佳實踐

  • 採用 using 區塊確保 Stream、FileStream、HttpWebResponse 全部正確釋放。
  • 8 KB 緩衝區平衡記憶體與 I/O 效能,支援任意大小圖片。

4. 回傳值語意明確

  • 1:下載並儲存成功
  • 0:URL 回應非圖片內容
  • 例外:參數錯誤、網路失敗、IO 錯誤等由呼叫端捕捉處理

進階擴充建議

  • 非同步版本:改用 HttpClient + await 避免阻塞 UI 執行緒。
  • 支援重導向與 Cookie:啟用 AllowAutoRedirect、CookieContainer。
  • 圖片驗證:下載後用 Image.FromStream 驗證是否真為合法圖片格式。
  • 並行下載:搭配 SemaphoreSlim 限制並發數,批次抓取大量圖片。

常見問題 FAQ

Q: 為什麼不直接用 WebClient.DownloadFile?
A: WebClient 已標記過時,且難以自訂 Header、Timeout、驗證 Content-Type 等細節。
Q: 如何處理 HTTPS 憑證錯誤?
A: 可在請求前註冊 ServicePointManager.ServerCertificateValidationCallback(僅限測試環境)。
Q: 大量下載時記憶體暴漲怎麼辦?
A: 確保緩衝區大小固定(如 8 KB),並及時 Dispose 所有 IDisposable 物件。

總結

本範例示範了從網路下載圖片的完整流程:參數驗證、HTTP 請求客製化、內容類型檢查、安全路徑組合、分塊串流寫入與資源釋放。掌握這些細節,即可在實務專案中建立穩健、安全的圖片下載功能。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved