byte
ストリームを使用してURLから画像を取得しようとしています。しかし、私はこのエラーメッセージを受け取ります:
このストリームは、シーク操作をサポートしていません。
これは私のコードです:
byte[] b;
HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create(url);
WebResponse myResp = myReq.GetResponse();
Stream stream = myResp.GetResponseStream();
int i;
using (BinaryReader br = new BinaryReader(stream))
{
i = (int)(stream.Length);
b = br.ReadBytes(i); // (500000);
}
myResp.Close();
return b;
私は間違った男を何をしていますか?
おそらくこのようなものが必要です。長さのチェックに失敗するか、BinaryReaderが舞台裏でシークを実行しています。
HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create(url);
WebResponse myResp = myReq.GetResponse();
byte[] b = null;
using( Stream stream = myResp.GetResponseStream() )
using( MemoryStream ms = new MemoryStream() )
{
int count = 0;
do
{
byte[] buf = new byte[1024];
count = stream.Read(buf, 0, 1024);
ms.Write(buf, 0, count);
} while(stream.CanRead && count > 0);
b = ms.ToArray();
}
編集:
リフレクターを使用して確認しましたが、失敗するのはstream.Lengthの呼び出しです。 GetResponseStreamはConnectStreamを返し、そのクラスのLengthプロパティは、見た例外をスローします。他の投稿者が述べたように、HTTP応答の長さを確実に取得することはできないため、これは理にかなっています。
代わりに StreamReader を使用してください:
HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create(url);
WebResponse myResp = myReq.GetResponse();
StreamReader reader = new StreamReader(myResp.GetResponseStream());
return reader.ReadToEnd();
(注-上記はバイト配列の代わりにString
を返します)
HTTP接続にその長さを確実に要求することはできません。サーバーに事前に長さを送信してもらうことは可能ですが、(a)そのヘッダーが欠落していることが多く、(b)正しいことが保証されていません。
代わりに:
byte[]
メソッドに渡す固定長Stream.Read
を作成しますList<byte>
を作成しますList.AddRange
を呼び出して、固定長バッファーの内容をバイトリストに追加しますRead
の最後の呼び出しは、要求したバイト数よりも少ない数を返すことに注意してください。 List<byte>
全体ではなくbyte[]
にそのバイト数だけを追加してください。そうしないと、リストの最後にゴミが入ります。
サーバーがHTTPヘッダーで長さの指定を送信しない場合、ストリームサイズは不明であるため、Length
プロパティを使用しようとするとエラーが発生します。
ストリームの終わりに達するまで、ストリームを小さなチャンクで読み取ります。
おそらく_System.Net.WebClient
_ APIを使用する必要があります。既にclient.OpenRead(url)
を使用している場合は、client.DownloadData(url)を使用します
_var client = new System.Net.WebClient();
byte[] buffer = client.DownloadData(url);
using (var stream = new MemoryStream(buffer))
{
... your code using the stream ...
}
_
明らかに、これはStream
が作成される前にすべてをダウンロードするため、Stream
を使用する目的に反する可能性があります。 webClient.DownloadData("https://your.url")
は、MemoryStream
に変換できるバイト配列を取得します。
受信者は送信者が送信するバイト数を知らないため、ストリームの長さをストリームから読み取ることはできません。プロトコルをhttpの上に置き、ストリームの最初の項目として長さを送信してみてください。
画像では、バイト数を読み取る必要はまったくありません。これを行うだけです:
Image img = null;
string path = "http://www.example.com/image.jpg";
WebRequest request = WebRequest.Create(path);
req.Credentials = CredentialCache.DefaultCredentials; // in case your URL has Windows auth
WebResponse resp = req.GetResponse();
using( Stream stream = response.GetResponseStream() )
{
img = Image.FromStream(stream);
// then use the image
}