首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >WebResponse contentLength属性是-1?

WebResponse contentLength属性是-1?
EN

Stack Overflow用户
提问于 2014-11-12 20:34:58
回答 3查看 5.4K关注 0票数 2

我有一个窗口应用程序,它获取URL并下载.jpeg文件。对于某些urls,ContentLength属性是-1,因此它会抛出异常。

这是我的代码:

代码语言:javascript
复制
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请求的一些信息:

代码语言:javascript
复制
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行抛出异常。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-11-12 20:45:28

没有要求网站提供一个内容长度的标题,也没有保证它是正确的。所以你不能依赖它。如果您试图使用ContentLength属性值来分配数组,或者用于任何比信息更重要的用途,您就会遇到麻烦。在一般情况下,这是不可靠的。

这很不幸,但你必须努力解决这个问题。一个解决方案是创建一个MemoryStream。然后从响应流读取数据块,并将它们写入内存流。继续到响应流结束。然后获取“`MemoryStream”缓冲区。

有点痛苦,但是如果ContentLength不可靠的话,这是最好的了。

例如:(请注意,我刚刚把它扔掉了,所以它可能不会100%工作。)但它应该给你这个想法。)

代码语言:javascript
复制
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.
票数 6
EN

Stack Overflow用户

发布于 2014-11-12 20:45:29

很简单:不要使用内容长度标题。如果省略它是完全正常的。只要数据是可用的,你就应该读取它。服务器将继续发送,直到完成为止。您可以使用Stream.CopyTo方法,它将将响应流复制到文件或MemoryStream或其他任何东西。这个方法也不需要知道长度,它只是一直读到流的末尾。

更新:代码如下所示

代码语言:javascript
复制
var resultStream = new MemoryStream()
using (var respStream = response.GetResponseStream())
    respStream.CopyTo(resultStream);
// now you can do anything with resultStream, like resultStream.ToArray()

或者您可以将其写入文件:

代码语言:javascript
复制
using (var fileStream = File.Create(@"d:\x\y.dat"))
using (var respStream = response.GetResponseStream())
    respStream.CopyTo(fileStream);
票数 5
EN

Stack Overflow用户

发布于 2017-02-16 16:16:02

只是为了贡献--内容长度标题没有什么问题--服务器将其设置为-1,因为它正在返回您的数据“分块”--正如您所推测的。分块的数据可以是无限的,因此内容长度没有意义。从技术上讲,当服务器知道它将返回的块的聚合大小时,它仍然可以返回一个长度,尽管我不知道这是否是规范的一部分。

上面的解决方案可以很好地解决这个问题--但是它与内容长度不可靠无关--它和提供它的服务一样可靠。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26896041

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档