1

外部サーバーから大量の画像を取得する必要がある ASP.NET サーバーを C# で作成しています。私が抱えている問題は、画像がメソッドから返されていることですが、半分しか読み込まれていないようです。

これは、私のサーバーを介してロードされたときのタイルの外観です (これは OSM サイクル マップ タイルです)。

tile.png

これは、ブラウザーで (もちろん同じ URL から) 開いた場合のタイルの外観です。

5.png

すべてのバイトがネットワーク経由で送信されていないことは明らかですが、どこで失われているのかはわかりません。これは私のコードがどのように見えるかです:

private byte[] GetTile(string url)
{
    var response = WebRequest.Create(url).GetResponse();

    Stream respStr = response.GetResponseStream();

    byte[] buf = new byte[response.ContentLength];
    respStr.Read(buf, 0, buf.Length);

    return buf;
}

これは、これを行う正しい方法のようにも感じられません。私のバイトはどこに行くのですか?関数から戻る前に、サーバーからのすべてのバイトが到着するのを待つ推奨される方法はありますか?

4

2 に答える 2

4

respStr.Read(buf, 0, buf.Length);Read は、バイトを読み取ることを保証しませんbuf.Length。その戻り値を確認する必要があります。または、単純に、次を使用して別のストリームにコピーできますCopyTo

private byte[] GetTile(string url)
{
    var response = WebRequest.Create(url).GetResponse();

    Stream respStr = response.GetResponseStream();

    MemoryStream m = new MemoryStream();
    respStr.CopyTo(m);

    return m.ToArray();
}

これにはWebClientを使用することもできます

private byte[] GetTile(string url)
{
    using (WebClient wc = new WebClient())
    {
        return wc.DownloadData(url);
    }
}
于 2012-11-05T00:06:53.920 に答える
1

それはあなたの問題に直接当てはまるので、私は単にJon Skeetの答えをオウム返しにしています. ストリームからのバイト配列の作成

おそらく、誰かが同様のキーワードを検索した場合、この回答が正しい方向を示している可能性があります。あなたはこの問題を抱えた最初の人ではないし、間違いなく最後の人でもないでしょう.

このStream.Read()メソッドは、ストリーム内のすべてのバイトが読み取られることを保証するものではありません。これは、ネットワーク ストリームを参照する場合に特に顕著です。戻り値をチェックして、ストリーム全体が消費されたことを完全に確認する必要があります。

public static byte[] ReadFully(Stream input)
{
    byte[] buffer = new byte[16*1024];
    using (MemoryStream ms = new MemoryStream())
    {
        int read;
        while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
        {
            ms.Write(buffer, 0, read);
        }
        return ms.ToArray();
    }
}
于 2012-11-05T00:02:15.187 に答える