Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用Webclient下载多个文件_C#_Webclient - Fatal编程技术网

C# 使用Webclient下载多个文件

C# 使用Webclient下载多个文件,c#,webclient,C#,Webclient,我试图通过NUnit测试用例从Web服务器下载文件,如下所示: [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()) { cl

我试图通过NUnit测试用例从Web服务器下载文件,如下所示:

[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));
    }
}

如何解决此问题?

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


我会在浏览器中下载文件,并使用firebug或类似程序检查通信。您必须看到响应中显式返回的内容长度。如果没有,您需要检查服务器,否则问题出在客户端。 实际上,我无法想象,如果确实返回了标题,客户端为什么不能读取标题


死而复生,但以下是答案

当服务器未在响应头中提供内容长度时,会发生此问题。你必须在服务器端解决这个问题

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

当我们调用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;
    }
//
///使用WebClient和流类从url获取文件大小
/// 
///网址
///只请求标题,而不是完整文件
///文件大小或-1(如果存在问题)。
静态Int64 GetFileSize(字符串地址,bool useHeaderOnly=false)
{
Int64 retVal=0;
尝试
{
如果(使用正面)
{
WebRequest=WebRequest.Create(地址);
request.Method=“HEAD”;
//WebResponse也必须关闭,否则我们会遇到连接限制挂起的问题。使用语句会自动关闭它。
使用(WebResponse=request.GetResponse())
{
if(响应!=null)
{
retVal=response.ContentLength;
//retVal=Convert.ToInt64(response.Headers[“Content Length]”);
}
}
请求=null;
}
其他的
{
使用(WebClient=newWebClient())
{
//流必须关闭,否则我们会遇到连接限制挂起的问题。使用语句会自动关闭它。
使用(流响应=client.OpenRead(地址))
{
retVal=Convert.ToInt64(client.ResponseHeaders[“Content Length]”);
}
}
}
}
捕获(例外情况除外)
{
控制台写入线(例如消息);
retVal=-1;
}
返回返回;
}

我会使用上面答案中显示的方法来获取标题:我不明白为什么我无法获取文件大小。我已经看过Daniel C提供的解决方案,但在client.ResponseHeaders上没有解决方案?我会在浏览器中下载文件,并使用firebug或类似程序检查通信。您必须看到响应中显式返回的内容长度。好的,我测试了通过FireFox下载文件,可以得到内容长度。问题是,当我尝试下载程序中的第二个文件并尝试通过Int64 bytes_total=Convert.ToInt64(client.ResponseHeaders[“Content Length”])获取文件大小时。然后就挂了。异步是否有问题???是否使用代理?下载后,您不仅可以检查文件大小吗?您还可以检查以下问题: