2

ゲーム Guild Wars 2 のこのサンプル API 呼び出しを呼び出すこのコードがあります。

        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);

これは、公式の Guild Wars 2 API へのサンプル呼び出しであり、イベントのリストとそのステータスを JSON 形式で返すことになっています。

ブラウザーでアドレスを呼び出し、データをテキスト エディターに貼り付けると、300 kb 強の正しい JSON 文字列が得られます。

ただし、このコードによって呼び出され、結果のバイト配列を見ると、最初の 3800 から 3900 バイトは正しく満たされていますが (数は呼び出しごとにわずかに異なります)、残りはすべてゼロです。

response.ContentLength は、ストリームの正しい長さ (300k を少し超える) を示し、stream.ReadByte() でテストすると、ストリームがそれらの 300k を配信することがわかります。3850 バイト マークの後はゼロです。

コードにエラーがありますか、またはこの問題の原因は何ですか? 別の方法で API を呼び出して、正しい完全な応答を取得できますか?

4

1 に答える 1

4

Readストリームに対する操作は、実際に読み取られたバイト数を返します。0 が返されるまで呼び出し続ける必要がstream.Read()あります。データがまだ到着していないだけです。

ブロックしない理由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();
}
于 2013-10-23T12:05:33.757 に答える