【问题标题】:HttpWebRequest partially fails to get dataHttpWebRequest 部分获取数据失败
【发布时间】:2013-11-01 16:36:28
【问题描述】:

我有这个代码,调用this sample API call of the game Guild Wars 2

        HttpWebRequest request = HttpWebRequest.Create("https://api.guildwars2.com/v1/events.json?world_id=1001") as HttpWebRequest;
        HttpWebResponse response = request.GetResponse() as HttpWebResponse;

        byte[] bytes = new byte[response.ContentLength];
        Stream stream = response.GetResponseStream();
        stream.Read(bytes, 0, bytes.Length);
        string result = Encoding.Default.GetString(bytes);

这是对官方激战 2 API 的示例调用,应该以 JSON 格式返回事件列表及其状态。

如果您在浏览器中调用该地址并将数据粘贴到文本编辑器中,它会提供一个正确的 JSON 字符串,大小略大于 300 kb。

但是,当被此代码调用并查看生成的字节数组时,前 3800-3900 个字节已正确填充(数字因调用而异),但其余部分均为零。

response.ContentLength 指示流的正确长度,略大于 300k,并且使用 stream.ReadByte() 进行测试告诉我流确实提供了这 300k,它在 3850 字节标记之后只是零。

我的代码中是否有错误,或者是什么导致了这个问题?我可以通过其他方式调用 API 以获得正确、完整的响应吗?

【问题讨论】:

标签: c# httpwebrequest


【解决方案1】:

流上的Read 操作返回实际读取的字节数。你应该一直调用stream.Read(),直到它返回0。数据还没有到达。

Read 不会阻止的原因是某些应用程序可能已经开始处理部分数据。

您可以使用以下代码:

HttpWebRequest request = HttpWebRequest.Create("https://api.guildwars2.com/v1/events.json?world_id=1001") as HttpWebRequest;
HttpWebResponse response = request.GetResponse() as HttpWebResponse;

byte[] bytes;
using (Stream stream = response.GetResponseStream())
using (MemoryStream buffer = new MemoryStream((int)response.ContentLength))
{
    byte[] chunk = new byte[4096];
    int bytesRead;
    while ((bytesRead = stream.Read(chunk, 0, chunk.Length)) > 0)
    {
        buffer.Write(chunk, 0, bytesRead);
    }
    bytes = buffer.ToArray();
}

【讨论】:

  • 谢谢,成功了。这有什么背景?这是否是 API 方面的限制,例如速度限制或块大小?
  • Read() 提前返回的原因是某些应用程序(例如流式视频)可以在请求完成之前开始处理数据。在我的示例中,块大小 4096 也可以是任何值。该值应该小于您一次收到的最大数据块,但如果太小,代码将浪费处理能力。
猜你喜欢
  • 2019-06-10
  • 2023-03-19
  • 1970-01-01
  • 2010-12-12
  • 2020-12-05
  • 1970-01-01
  • 2010-09-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多