我有一个窗口应用程序,它获取URL并下载.jpeg文件。对于某些urls,ContentLength属性是-1,因此它会抛出异常。
这是我的代码:
var url = new Uri(sUrlToReadFileFrom[i]);
_request = (HttpWebRequest)WebRequest.Create(url);
var response = (System.Net.WebResponse)_request.GetResponse();
_response = response;
_response.Close();下面是url:1.jpg,下面是关于我的http请求的一些信息:
Headers = {Transfer-Encoding: chunked
Connection: keep-alive
Content-Disposition: inline; filename="phpThumb_generated_thumbnail.jpeg"
Content-Type: image/jpeg
Date: Wed, 12 Nov 2014 00:31:29 GMT
Server: nginx
X-Powered-By: PleskLin}我认为分块的头造成了问题,但我已经搜索了2天,没有好的解决方案,或者我找不到一个好的解决方案。
以下是错误的屏幕截图:

正如您在第130行中看到的,因为_response.ContentLength已经是-1,因此iSize将是-1,并在第149行抛出异常。
发布于 2014-11-12 20:45:28
没有要求网站提供一个内容长度的标题,也没有保证它是正确的。所以你不能依赖它。如果您试图使用ContentLength属性值来分配数组,或者用于任何比信息更重要的用途,您就会遇到麻烦。在一般情况下,这是不可靠的。
这很不幸,但你必须努力解决这个问题。一个解决方案是创建一个MemoryStream。然后从响应流读取数据块,并将它们写入内存流。继续到响应流结束。然后获取“`MemoryStream”缓冲区。
有点痛苦,但是如果ContentLength不可靠的话,这是最好的了。
例如:(请注意,我刚刚把它扔掉了,所以它可能不会100%工作。)但它应该给你这个想法。)
var response = (HttpWebResponse)request.GetResponse();
byte[] data; // will eventually hold the result
// create a MemoryStream to build the result
using (var mstrm = new MemoryStream())
{
using (var s = response.GetResponseStream())
{
var tempBuffer = new byte[4096];
int bytesRead;
while ((bytesRead = s.Read(tempBuffer, 0, tempBuffer.Length)) != 0)
{
mstrm.Write(tempBuffer, 0, bytesRead);
}
}
mstrm.Flush();
data = mstrm.GetBuffer();
}
// at this point, the data[] array holds the data read from the stream.
// data.Length will tell you how large it is.发布于 2014-11-12 20:45:29
很简单:不要使用内容长度标题。如果省略它是完全正常的。只要数据是可用的,你就应该读取它。服务器将继续发送,直到完成为止。您可以使用Stream.CopyTo方法,它将将响应流复制到文件或MemoryStream或其他任何东西。这个方法也不需要知道长度,它只是一直读到流的末尾。
更新:代码如下所示
var resultStream = new MemoryStream()
using (var respStream = response.GetResponseStream())
respStream.CopyTo(resultStream);
// now you can do anything with resultStream, like resultStream.ToArray()或者您可以将其写入文件:
using (var fileStream = File.Create(@"d:\x\y.dat"))
using (var respStream = response.GetResponseStream())
respStream.CopyTo(fileStream);发布于 2017-02-16 16:16:02
只是为了贡献--内容长度标题没有什么问题--服务器将其设置为-1,因为它正在返回您的数据“分块”--正如您所推测的。分块的数据可以是无限的,因此内容长度没有意义。从技术上讲,当服务器知道它将返回的块的聚合大小时,它仍然可以返回一个长度,尽管我不知道这是否是规范的一部分。
上面的解决方案可以很好地解决这个问题--但是它与内容长度不可靠无关--它和提供它的服务一样可靠。
https://stackoverflow.com/questions/26896041
复制相似问题