2010-09-01 39 views
58

我想從網站下載圖像。我使用的代碼在圖像可用時工作正常。如果圖片不可用,則會造成問題。如何驗證圖像的可用性?從.NET/C中的網站下載圖像#

代碼:

方法1:

WebRequest requestPic = WebRequest.Create(imageUrl); 

WebResponse responsePic = requestPic.GetResponse(); 

Image webImage = Image.FromStream(responsePic.GetResponseStream()); // Error 

webImage.Save("D:\\Images\\Book\\" + fileName + ".jpg"); 

方法2:

WebClient client = new WebClient(); 
Stream stream = client.OpenRead(imageUrl); 

bitmap = new Bitmap(stream); // Error : Parameter is not valid. 
stream.Flush(); 
stream.Close(); 
client.dispose(); 

if (bitmap != null) 
{ 
    bitmap.Save("D:\\Images\\" + fileName + ".jpg"); 
} 

編輯:

流具有下面的語句:

 Length '((System.Net.ConnectStream)(str)).Length' threw an exception of type 'System.NotSupportedException' long {System.NotSupportedException} 
    Position '((System.Net.ConnectStream)(str)).Position' threw an exception of type 'System.NotSupportedException' long {System.NotSupportedException} 
ReadTimeout 300000 int 
WriteTimeout 300000 int 
+0

包裹有問題的語句'嘗試 - catch',併爲我們提供了異常的詳細信息。 – gimel 2010-09-01 07:25:31

+0

line bitmap = new Bitmap(stream);顯示錯誤:參數無效。 – Geeth 2010-09-01 09:26:37

回答

153

沒有必要讓任何圖像類,你可以簡單地調用WebClient.DownloadFile

string localFilename = @"c:\localpath\tofile.jpg"; 
using(WebClient client = new WebClient()) 
{ 
    client.DownloadFile("http://www.example.com/image.jpg", localFilename); 
} 

更新
既然你要檢查文件是否存在,下載文件如果是這樣,最好在相同的請求內完成此操作。因此,這裏是一個方法,將做到這一點:

private static void DownloadRemoteImageFile(string uri, string fileName) 
{ 
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri); 
    HttpWebResponse response = (HttpWebResponse)request.GetResponse(); 

    // Check that the remote file was found. The ContentType 
    // check is performed since a request for a non-existent 
    // image file might be redirected to a 404-page, which would 
    // yield the StatusCode "OK", even though the image was not 
    // found. 
    if ((response.StatusCode == HttpStatusCode.OK || 
     response.StatusCode == HttpStatusCode.Moved || 
     response.StatusCode == HttpStatusCode.Redirect) && 
     response.ContentType.StartsWith("image",StringComparison.OrdinalIgnoreCase)) 
    { 

     // if the remote file was found, download oit 
     using (Stream inputStream = response.GetResponseStream()) 
     using (Stream outputStream = File.OpenWrite(fileName)) 
     { 
      byte[] buffer = new byte[4096]; 
      int bytesRead; 
      do 
      { 
       bytesRead = inputStream.Read(buffer, 0, buffer.Length); 
       outputStream.Write(buffer, 0, bytesRead); 
      } while (bytesRead != 0); 
     } 
    } 
} 

簡單地說,它使文件的請求,驗證響應代碼是OKMovedRedirect之一,也是ContentType是圖片。如果這些條件成立,則文件被下載。

+4

不要忘記處理'WebClient'。 – 2010-09-01 07:24:00

+0

@Darin:謝謝。修正了。 – 2010-09-01 07:26:01

+0

@Geetha:如果您嘗試導航到Web瀏覽器中的給定URL,您會看到圖片嗎? – 2010-09-01 08:08:29

24

我在稍作修改項目中使用上述弗雷德裏克的代碼,想我會分享:

private static bool DownloadRemoteImageFile(string uri, string fileName) 
{ 
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri); 
    HttpWebResponse response; 
    try 
    { 
     response = (HttpWebResponse)request.GetResponse(); 
    } 
    catch (Exception) 
    { 
     return false; 
    } 

    // Check that the remote file was found. The ContentType 
    // check is performed since a request for a non-existent 
    // image file might be redirected to a 404-page, which would 
    // yield the StatusCode "OK", even though the image was not 
    // found. 
    if ((response.StatusCode == HttpStatusCode.OK || 
     response.StatusCode == HttpStatusCode.Moved || 
     response.StatusCode == HttpStatusCode.Redirect) && 
     response.ContentType.StartsWith("image", StringComparison.OrdinalIgnoreCase)) 
    { 

     // if the remote file was found, download it 
     using (Stream inputStream = response.GetResponseStream()) 
     using (Stream outputStream = File.OpenWrite(fileName)) 
     { 
      byte[] buffer = new byte[4096]; 
      int bytesRead; 
      do 
      { 
       bytesRead = inputStream.Read(buffer, 0, buffer.Length); 
       outputStream.Write(buffer, 0, bytesRead); 
      } while (bytesRead != 0); 
     } 
     return true; 
    } 
    else 
     return false; 
} 

主要變化如下:

  • 使用try/catch語句的的GetResponse( ),因爲我在遠程文件返回時遇到異常404
  • 返回布爾值
+1

謝謝 - 看起來像寫得很好的代碼,並且在我的應用程序中運行良好 – bernhardrusch 2013-05-03 08:42:14

+0

爲什麼在拋出異常時返回布爾標誌?在出現性能問題之前總是會更好。 SRP不允許使用這些方法。 – 2015-09-16 04:58:52

0
 private static void DownloadRemoteImageFile(string uri, string fileName) 
     { 
      HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri); 
      HttpWebResponse response = (HttpWebResponse)request.GetResponse(); 

      if ((response.StatusCode == HttpStatusCode.OK || 
       response.StatusCode == HttpStatusCode.Moved || 
       response.StatusCode == HttpStatusCode.Redirect) && 
       response.ContentType.StartsWith("image", StringComparison.OrdinalIgnoreCase)) 
      { 
       using (Stream inputStream = response.GetResponseStream()) 
       using (Stream outputStream = File.OpenWrite(fileName)) 
       { 
        byte[] buffer = new byte[4096]; 
        int bytesRead; 
        do 
        { 
         bytesRead = inputStream.Read(buffer, 0, buffer.Length); 
         outputStream.Write(buffer, 0, bytesRead); 
        } while (bytesRead != 0); 
       } 
      } 
     } 
+0

也許你可以解釋這段代碼,並_why_它的作品? – 2016-12-05 16:32:00

2

也可以使用DownloadData方法

private byte[] GetImage(string iconPath) 
    { 
     using (WebClient client = new WebClient()) 
     { 
      byte[] pic = client.DownloadData(iconPath); 
      //string checkPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) [email protected]"\1.png"; 
      //File.WriteAllBytes(checkPath, pic); 
      return pic; 
     } 
    }