如何知道响应的长度 (HttpWebRequest.GetResponse().GetResponseStream())

6
有没有办法知道响应流的长度,以便我可以向用户显示下载的百分比进度而不是一个不确定的进度?我发现响应看起来像下面这样,不可查找且没有长度。
3个回答

14

尝试使用 WebResponse.ContentLength 属性。如果返回值为 -1,则意味着远程服务器没有向您发送响应正文的长度,因此您无法在完全读取它之前确定响应的长度。


我在 PHP 中进行了一项测试,其中我设置了内容长度(pastebin 上的代码),不确定是否做得正确,但我仍然得到了一个无法搜索的流... 嗯... 我稍后会尝试一个真正的下载,也许是从 download.com 上下载... - Jiew Meng
2
WebResponse.GetResponseStream是不可寻址的。它是一个只能向前、只读的流。但是,如果设置了ContentLength头,则通常是可靠的。您不应该需要寻址。 - Jim Mischel
小提示:返回的 长度以字节为单位!来源:https://learn.microsoft.com/en-us/dotnet/api/system.net.httpwebresponse.contentlength?view=netcore-3.1 - ssamko
好的....是吗?流对象代表字节流,所以我认为这是相当显然的。 - cdhowie

1

如果您感兴趣,我有一个代码参考库,其中包括一个WebHelper类。它类似于WebClient类(包括报告进度的能力),但更加灵活。它存储在CodePlex上,项目名称为BizArk

它使用Response.ContentLength属性来确定响应的长度。

ContentLength属性只是作为头部的一部分从服务器发送。有些情况下,服务器在发送头部之前可能不知道响应的长度。例如,如果您正在下载一个动态生成的网页,并且在服务器上关闭了缓冲。


-4
我创建了一个包装类WebStreamWithLength(由于我不需要它,所以未实现seek方法),已经解决了问题。
你应该像这样使用它。
WebRequest req = HttpWebRequest.Create(link);
WebResponse res = req.GetResponse();
var stream = res.GetResponseStream();
var streamWithLenght = new WebStreamWithLenght(stream, res.ContentLength);

    public class WebStreamWithLenght : Stream
    {
        long _Lenght;
        Stream _Stream;
        long _Position;

        public WebStreamWithLenght(Stream stream, long lenght)
        {
            _Stream = stream;
            _Lenght = lenght;
        }

        public override bool CanRead
        {
            get { return _Stream.CanRead; }
        }

        public override bool CanSeek
        {
            get { return true; }
        }

        public override bool CanWrite
        {
            get { return _Stream.CanWrite; }
        }

        public override void Flush()
        {
            _Stream.Flush();
        }

        public override long Length
        {
            get { return _Lenght; }
        }

        public override long Position { get; set; }

        public override int Read(byte[] buffer, int offset, int count)
        {
            var result = _Stream.Read(buffer, offset, count);
            Position += count;
            return result;
        }

        public override long Seek(long offset, SeekOrigin origin)
        {
            throw new NotImplementedException();
        }

        public override void SetLength(long value)
        {
            _Lenght = value;
        }

        public override void Write(byte[] buffer, int offset, int count)
        {
            Write(buffer, offset, count);
        }
    }

为什么会有踩?有人能解释一下为什么这不是一个好的答案吗? - setholopolus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接