- - PR -
[2005][C#]WebRequestで取得したStreamをそのままファイルに保存したい
1
投稿者 | 投稿内容 | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2007-05-30 11:47
WebRequestでWebサーバからファイルをダウンロードしています。
WebClientはTimeoutが設定できないのでWebRequestのほうを使用しています。 現在WebResponseの取得はできていますが、 それをファイルに保存するところでとまっています。 WebResponse→Stream→バイト配列→FileStreamで保存 という流れを考えていたのですが、 Stream→バイト配列のところでうまくいきません。 StreamのReadByteメソッドをループでは時間がかかるとのことなので Readメソッドでバイト配列に変換したいのですが、 StreamのLengthプロパティでシークできない旨のエラーがでます。 WebClientのDownloadDataメソッドではうまくいっているURLなのですが・・。 (テストとしてhttp://www.goo.ne.jp/index.htmlをダウンロードしていますが、 実際はexeやDLLをダウンロードします。) Streamをバイト配列に変換するにはどうしたらよいでしょうか。 また、バイト配列に変換せずStreamから直接ファイルに保存とかはできるのでしょうか。 | ||||||||||||
|
投稿日時: 2007-05-30 12:08
全体の長さが取得できないストリームから読み出す場合、適当な大きさのバッファ(byte 配列)を用意し、0 以上を返す間 Read メソッドを繰り返し呼び出すのが一般的です。最適なバッファサイズはストリーム元など環境によって変わります。
読み出したバッファは、ファイルに保存するならそのまま FileStream に書き出せばいいでしょう。Read メソッドの返値が書き込むべきサイズも意味します。書き出したら次の Read へ。
標準クラスライブラリには存在していません。 | ||||||||||||
|
投稿日時: 2007-05-30 12:48
そういうStreamを一度作ってしまうと便利かな。 | ||||||||||||
|
投稿日時: 2007-05-30 14:08
Hongliangさん
アドバイスありがとうございます。 なるほど。1バイトずつではなくnバイトずつ読み込み速度アップということですね? アドバイスを参考にして以下のようなコードを組んで見みした。
これでうまくファイルに保存されるようになりました。 が、本来Readできるはずのものが途中でぶちきれしまいます。 Streamの全てをReadしきれていないようです。 切れる位置は、現在2パターンあります。 バッファするサイズがよくないのでしょうか・・・? (※HttpWebRequest、HttpWebResponseを利用したGET、 かつStreamReaderクラスを使用した場合は71KBほどになります。) スレの趣旨からは外れますが、お分かりの方がいらっしゃれば 教えていただけないでしょうか。 なちゃさん
そうですね。今回は一箇所でしか使わないので 直に書いてしまう予定ですが。 今後そんなクラスを作っておくと便利ですよね。 検討してみます。 | ||||||||||||
|
投稿日時: 2007-05-30 14:32
Stream.Read の解説にはこう書かれています。
つまり、Stream.Read の返値が第三引数未満の値になったとしても、イコールストリームの末尾と考えることはできません。ストリームの末尾と判断できるのは 0 が返されたときだけです。 ちなみに私はよくこんな感じに書きます。
[追記] あ、それからループ内で毎回バッファを new するのはあんまり好ましくないかと。 使いまわして問題ないものですし。 [ メッセージ編集済み 編集者: Hongliang 編集日時 2007-05-30 14:35 ] | ||||||||||||
|
投稿日時: 2007-05-30 16:06
うーん、なるほど。MSDNの文言を正しく理解できていなかったようです。 Readの戻り値が0の時だけbreakすることで解決しました。
そうですね。ここも修正しました。 ありがとうございました。 |
1