用于下载图像的 c# foreach 循环只工作一次

c# foreach loop for downloading image just works once

我正在创建一个从网站 url 下载图像的 pc window 应用程序。允许用户 select 下载到哪个文件夹。

但我遇到的问题是 foreach 循环只执行一次这个过程...

public bool Url_checker(string link)
{
    try
    {
        //Creating the HttpWebRequest
        HttpWebRequest request = WebRequest.Create(link.Trim()) as HttpWebRequest;
        //Setting the Request method HEAD, you can also use GET too.
        request.Method = "HEAD";
        //Getting the Web Response.
        HttpWebResponse response = request.GetResponse() as HttpWebResponse;
        //Returns TRUE if the Status code == 200
        return (response.StatusCode == HttpStatusCode.OK);
    }
    catch (WebException)
    {
        return false;
    }
}

private void submit_Click(object sender, EventArgs e)
{
    FolderBrowserDialog folderBrowserDialog1 = new FolderBrowserDialog();
    folderBrowserDialog1.ShowDialog();
    string saveToThisFolder = folderBrowserDialog1.SelectedPath ;
    int i = 0;
    var di = new DirectoryInfo(saveToThisFolder);
    di.Attributes &= ~FileAttributes.ReadOnly;

    int counter = 0;
       foreach (string x in urllist.Lines)
       {
           string EndOfURL = x.Substring(x.Length - 4);
           if (Url_checker(x) && (EndOfURL == ".jpg" || EndOfURL == ".gif" || EndOfURL == ".jpeg" || EndOfURL == ".png"))
           {
              byte[] data;
             //using (WebClient client = new WebClient())
              //{
              WebClient client = new WebClient();
                  data = client.DownloadData(x);
             // }

              File.WriteAllBytes(saveToThisFolder + @"\" + (i++ + EndOfURL), data);
              counter++;
              workingURL.Text += x; //+ System.Environment.NewLine
           }
          else
          {

              errorURL.Text += (x + System.Environment.NewLine);
          }
       }


    folderBrowserDialog1.Dispose();
}

GUI设计来了。

最后的结果是这样的,

它只打印和下载一次。就好像,它只读取文本框的第一行。或者foreach循环错误。

谢谢

这是新代码,经过清理 private void submit_Click(object sender, EventArgs e) {

        FolderBrowserDialog folderBrowserDialog1 = new FolderBrowserDialog();
        folderBrowserDialog1.ShowDialog();
        string saveToThisFolder = folderBrowserDialog1.SelectedPath;
        int i = 0;
        var di = new DirectoryInfo(saveToThisFolder);
        di.Attributes &= ~FileAttributes.ReadOnly;

        int counter = 0;
        foreach (string x in urllist.Lines)
        {
            try
            {
                string EndOfURL = x.Substring(x.Length - 4);
                if (Url_checker(x) && (EndOfURL == ".jpg" || EndOfURL == ".gif" || EndOfURL == ".jpeg" || EndOfURL == ".png"))
                {

                    byte[] data;
                    using (WebClient client = new WebClient())
                    {                            
                      data = client.DownloadData(x);
                      File.WriteAllBytes(saveToThisFolder + @"\" + ("MotivatinalQuoteImage" + (i++) + EndOfURL), data);
                      counter++;
                      workingURL.Text += x + System.Environment.NewLine;
                    }
                }
                else
                {
                    errorURL.Text += (x + System.Environment.NewLine);
                }
            }
            catch (Exception ex)
            {
                errorURL.Text += ex;
            }

        }
        folderBrowserDialog1.Dispose();
    }

所以调试后,我发现错误在

之间
                       byte[] data;
                       using (WebClient client = new WebClient())
                       {
                           data = client.DownloadData(x);
                           File.WriteAllBytes(saveToThisFolder + @"\" + ("MotivatinalQuoteImage" + (i++) + EndOfURL), data);
                           counter++;
                           workingURL.Text += x + System.Environment.NewLine;
                       } 

这是我等待时发生的事情。之后它只下载了 1 张图片。

尽量把foreach的内容放在try/catch下... 从 string EndOfUrl =....

开始

我认为这实际上是您的 Url_checker 方法在捕获异常时返回 false。
当我逐字测试你的代码时,我得到了相同的结果,它只下载了第一张图片。
如果我使用以下 Url_checker 每次工作时都会处理 HttpWebResponse

    public bool Url_checker(string link)
    {
        try
        {
            HttpWebRequest request = WebRequest.Create(link.Trim()) as HttpWebRequest;
            request.Method = "HEAD";

            using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
            {
                return (response.StatusCode == HttpStatusCode.OK);
            }
        }
        catch (WebException)
        {
            return false;
        }
    }

这是因为您必须在响应完成后对其进行处理,否则底层基础架构不知道您对结果做了什么,也无法为下一个响应重用该连接。

编辑:比我聪明的人能否澄清这是否是因为没有完整阅读回复,所以您必须明确处理它?

编辑 2:没关系。来自 HttpWebResponse 的文档:

https://msdn.microsoft.com/en-us/library/system.net.httpwebresponse%28v=vs.110%29.aspx

You should never directly create an instance of the HttpWebResponse class. Instead, use the instance returned by a call to HttpWebRequest.GetResponse. You must call either the Stream.Close or the HttpWebResponse.Close method to close the response and release the connection for reuse. It is not necessary to call both Stream.Close and HttpWebResponse.Close, but doing so does not cause an error.

编辑3:哎呀,原来OP也是对的。我在测试时习惯性地将他的 WebClient 包裹在 using 中(他最初这样做)并且它也有效。作为记录,您也可以将 using 放在 FolderBrowserDialog 上,而不是自己处理它,尽管两者都有效。

byte[] data;
using (WebClient client = new WebClient())
{
    data = client.DownloadData(x);
}
File.WriteAllBytes(saveToThisFolder + @"\" + (i++ + EndOfURL), data);
counter++;
workingURL.Text += x + System.Environment.NewLine;

我是说

foreach (string x in urllist.Lines)
   {
try
{
       string EndOfURL = x.Substring(x.Length - 4);
       if (Url_checker(x) && (EndOfURL == ".jpg" || EndOfURL == ".gif" || EndOfURL == ".jpeg" || EndOfURL == ".png"))
       {
          byte[] data;
         //using (WebClient client = new WebClient())
          //{
          WebClient client = new WebClient();
              data = client.DownloadData(x);
         // }

          File.WriteAllBytes(saveToThisFolder + @"\" + (i++ + EndOfURL), data);
          counter++;
          workingURL.Text += x; //+ System.Environment.NewLine
       }
      else
      {

          errorURL.Text += (x + System.Environment.NewLine);
      }
   }
}
catch(Exception ex)
{//todo : add some logging here}

所以你可以检查 SubString 方法是否有错误

问题是这个程序只循环一次!但是,没有下面的代码。 FOR 循环完美运行。下面的代码是问题所在。

byte[] data;
                        using (WebClient client = new WebClient())
                        {                            
                          data = client.DownloadData(x);
                          File.WriteAllBytes(saveToThisFolder + @"\" + ("MotivatinalQuoteImage" + (i++) + EndOfURL), data);
                          counter++;
                          workingURL.Text += x + System.Environment.NewLine;
                        }