You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用HttpWebResponse流实例化StreamReader失败:Stream不可读

解决HttpWebResponse读取分块压缩响应时的“Stream was not readable”问题

嘿,我之前也碰到过一模一样的问题!咱们先拆解下问题根源,再一步步修复代码。

首先,你代码里设置了request.Headers.Add("Accept-Encoding", "gzip, deflate"),这意味着服务器会返回压缩后的响应流(gzip或deflate格式),但你直接用StreamReader去读这个原始流,肯定会出错——因为压缩流不是可读的文本流,这就是你看到System.ArgumentException: Stream was not readable的原因。另外,分块响应的处理其实不需要你手动操作,压缩流会自动帮你处理分块的拼接。

修复步骤

  • 判断响应的压缩格式:从HttpWebResponse的ContentEncoding属性获取服务器实际返回的压缩类型。
  • 用压缩流包装响应流:根据压缩类型,分别使用GZipStream或DeflateStream来解压流。
  • 通过解压后的流读取文本:把解压后的流传给StreamReader,就能正常读取完整响应了。

修改后的完整代码

using System.IO.Compression; // 记得添加这个命名空间

public bool Login() {
    try {
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(@"http://WEBSITE-REMOVED/CheckAccess");
        request.CookieContainer = CookieContainer;
        //Set POST data.
        string postData = "institution=AAA";
        postData += "&ismobile=false";
        postData += "&id=BBB";
        postData += "&password=CCC";
        byte[] data = Encoding.ASCII.GetBytes(postData);
        //Configure HTTP POST request.
        request.Headers.Clear();
        request.Method = "POST";
        request.Accept = @"text/html, application/xhtml+xml, image/jxr, */*";
        request.Referer = @"http://WEBSITE-REMOVED/entry.html";
        request.Headers.Add("Accept-Language", "en-US");
        request.UserAgent = @"Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko";
        request.ContentType = @"application/x-www-form-urlencoded";
        request.Headers.Add("Accept-Encoding", "gzip, deflate");
        request.Host = "op.responsive.net";
        request.ContentLength = data.Length;
        request.KeepAlive = true;
        request.Headers.Add("Cache-Control", "no-cache");
        
        using (Stream stream = request.GetRequestStream()) {
            stream.Write(data, 0, data.Length);
        }
        
        using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
        {
            Stream responseStream = response.GetResponseStream();
            // 处理压缩流
            if (response.ContentEncoding.Equals("gzip", StringComparison.OrdinalIgnoreCase))
            {
                responseStream = new GZipStream(responseStream, CompressionMode.Decompress);
            }
            else if (response.ContentEncoding.Equals("deflate", StringComparison.OrdinalIgnoreCase))
            {
                responseStream = new DeflateStream(responseStream, CompressionMode.Decompress);
            }
            
            // 现在可以正常读取完整响应了
            using (StreamReader sr = new StreamReader(responseStream, Encoding.UTF8))
            {
                string fullResponse = sr.ReadToEnd();
                // 这里可以处理返回的响应内容,比如判断登录是否成功
                // TO-DO: 逻辑处理
            }
        }
    }
    catch(Exception ex) {
        File.AppendAllText(ErrorLogDirectory + "Errors.txt", "Login() Exception\r\n" + System.DateTime.Now + "\r\n" + ex.ToString() + Environment.NewLine);
    }
    return false;
}

额外注意点

  • 必须引用System.IO.Compression命名空间,否则GZipStream和DeflateStream会报找不到类型的错误。
  • sr.ReadToEnd()会一次性读取所有分块响应的内容,不需要手动处理分块拼接逻辑。
  • 所有流都用using块包裹,确保资源自动释放,避免流泄漏问题。

这样修改后,你应该就能正常读取到完整的响应内容,不会再碰到流不可读的错误了!

内容的提问来源于stack exchange,提问作者Foxslaughter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:54:15