使用Webclient下载多个文件

时间:2014-05-30 08:38:23

标签: c# webclient

我正在尝试通过NUnit-testcase从webserver下载文件,如下所示:

[TestCase("url_to_test_server/456.pdf")]
[TestCase("url_to_test_server/457.pdf")]
[TestCase("url_to_test_server/458.pdf")]
public void Test(string url) 
{
    using (WebClient client = new WebClient())
    {
        client.Headers.Add("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0)");
        client.DownloadFile(new Uri(url), @"C:\Temp\" + Path.GetFileName(url));
    }
}

此代码有效,但当我尝试获取文件大小时,它会挂起。

[TestCase("url_to_test_server/456.pdf")]
[TestCase("url_to_test_server/457.pdf")]
[TestCase("url_to_test_server/458.pdf")]
public void Test(string url) 
{
    using (WebClient client = new WebClient())
    {
        client.Headers.Add("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0)");
        client.OpenRead(url);
        Int64 bytes_total = Convert.ToInt64(client.ResponseHeaders["Content-Length"]);
        client.DownloadFile(new Uri(url), @"C:\Temp\" + Path.GetFileName(url));
    }
}

如何解决这个问题?

2 个答案:

答案 0 :(得分:0)

您必须确保您的服务器也支持此标头。它似乎不是一个客户问题。

我会在浏览器中下载该文件,并使用firebug或类似的程序检查通信。您必须在响应中显示返回的Content-length。如果没有,您需要检查服务器,否则您的问题是在客户端。 我实际上无法想象一个原因,如果它确实正在返回,客户端无法读取标题。

enter image description here

答案 1 :(得分:0)

唤醒死岗,但这是答案......

当服务器未在响应标头中提供Content-Length时,会发生此问题。你必须在服务器端解决这个问题。

发生这种情况的另一个原因是我们已达到服务器的连接限制。 所以我假设你的问题是相似的,它在第二次或第三次尝试循环。

当我们调用OpenRead时,它会打开一个流。我们只需要在获取文件大小后关闭此流,以使其正常工作。

以下是我用来获取大小的代码:

    /// <summary>
    /// Gets file size from a url using WebClient and Stream classes
    /// </summary>
    /// <param name="address">url</param>
    /// <param name="useHeaderOnly">requests only headers instead of full file</param>
    /// <returns>File size or -1 if their is an issue.</returns>
    static Int64 GetFileSize(string address, bool useHeaderOnly = false)
    {
        Int64 retVal = 0;
        try
        {
            if(useHeaderOnly)
            {
                WebRequest request = WebRequest.Create(address);
                request.Method = "HEAD";

                // WebResponse also has to be closed otherwise we get the same issue of hanging on the connection limit. Using statement closes it automatically.
                using (WebResponse response = request.GetResponse())
                {
                    if (response != null)
                    {
                        retVal = response.ContentLength;
                        //retVal =  Convert.ToInt64(response.Headers["Content-Length"]);
                    }
                }
                request = null;
            }
            else
            {
                using (WebClient client = new WebClient())
                {
                    // Stream has to be closed otherwise we get the issue of hanging on the connection limit. Using statement closes it automatically.
                    using (Stream response = client.OpenRead(address))
                    {
                        retVal = Convert.ToInt64(client.ResponseHeaders["Content-Length"]);
                    }
                }
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
            retVal = -1;
        }


        return retVal;
    }
相关问题