VB2003でファイルのダウンロードについて教えて

このQ&Aのポイント
  • VB.NET2003でファイルをダウンロードする方法について教えてください。
  • ブラウザでファイルをダウンロードする場合と比べて、VB2003でのダウンロードに時間がかかる理由を教えてください。
  • VB2003でのファイルのダウンロード方法で、CPUの負荷を軽減する方法を教えてください。
回答を見る
  • ベストアンサー

VB2003でファイルのダウンロードについて教えて

Dim req As HttpWebRequest = CType(WebRequest.Create(url), HttpWebRequest) Dim res As WebResponse = req.GetResponse() Dim resStream As Stream = res.GetResponseStream() Dim fs As New System.IO.FileStream(SaveName, FileMode.Create, FileAccess.Write) Dim b As Integer While True b = resStream.ReadByte() If b = -1 Then Exit While fs.WriteByte(Convert.ToByte(b)) End While VB.NET2003ですが上記の方法でファイルをダウンロードしているのですが、 ブラウザで表示して転送される場合は30秒ほどなのですが、 この方法でダウンロードすると130秒くらいかかってしまいます。 ディスクに書き込む動作が足を引っ張っているのかと思って 下から2行目を消して計測してみたのですがそれでも10秒ほどしか短縮しませんでした。 タスクマネージャーで確認してもCPUリソースが50をずっと超えているのですが ブラウザなどでダウンロードする時のように高速でCPUに負担をかけずにダウンロードするには どんな方法でやれば良いでしょうか? よろしくお願い致します。

質問者が選んだベストアンサー

  • ベストアンサー
  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.1

1バイト毎読み込んで、書き込んでいれば遅いのは当然でしょう dim buf(8191) as Byte, nn, nLen, cnt as Integer nn = 0 cnt = 0 do   ' バッファに読み込む、読み込まれた数がnLenに代入される   nLen = resStream.Read( buf, 0, buf.Length )   if nLen > 0 then     ' 読み込んだバイト数分書き込む     fs.Write( buf, 0, nLen )     ' 途中経過が必要なければ以下をコメントアウト     nn += nLen     cnt += 1     if cnt mod 20 = 19 then       Application.doEvents()       Label1.Text = nLen.ToString()     end if     ' ここまで   end if loop while nLen > 0 といった具合にして見ましょう 配列bufの大きさは読み込むファイルや、Web環境に応じて加減してください 上記の例では 8KBごと読むようにしております

goo081102
質問者

お礼

ご回答ありがとうございます。 完璧なサンプルを書いて頂いて大変ありがとうございます。 ダウンロードが遅いのとCPU負荷が高いという両方が解決できました。 ありがとうございました。

関連するQ&A

  • C#でストリームの保存の仕方

    以下のコードのストリームstの保存を行いたいのですが、Streamのインスタンスをnewで作れないので どのようにすればよいでしょうか。お願いします。 HttpWebRequest webreq = (HttpWebRequest)WebRequest.Create("http://www.***.co.jp"); HttpWebResponse webres = (HttpWebResponse)webreq.GetResponse(); Stream st = webres.GetResponseStream();

  • [C#]htmlを取得できないページがある。

    C#でhtmlソースを取得したいのですが、取得できるページと出来ないページがあって困っています。 取得方法は以下の方法を使用しています。 ===ここから=== HttpWebRequest req = WebRequest.Create(url) as HttpWebRequest; HttpWebResponse res = null; try { res = req.GetResponse() as HttpWebResponse; } catch { MessageBox.Show(url + "指定した Web ページが応答していません!", "エラー"); } StreamReader reader = new StreamReader(res.GetResponseStream(), Encoding.GetEncoding(encode)); string htmlsource = reader.ReadToEnd(); reader.Close(); =================== htmlsourceにソースが入るのですが、取得できないページも一応ソースは取得できるのですが、 実際にIEなどのブラウザで表示した場合のソースと異なります。 ユーザーエージョンとして req.UserAgent = "User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:16.0) Gecko/20100101 Firefox/16.0"; を設定しても結果は同じでした。 ■取得できるページ例 http://www.amazon.co.jp/s/ref=sr_nr_n_1/375-1273809-4334332?rh=n%3A465392%2Cn%3A!465610%2Cn%3A571582&bbn=465610&ie=UTF8&qid=1376454464&rnid=465610&lo=stripbooks ■取得できないページ例 http://www.amazon.co.jp/s/ref=sr_nr_n_3?rh=n%3A465392%2Cn%3A!465610%2Cn%3A492152&bbn=465610&ie=UTF8&qid=1376454590&rnid=465610&lo=stripbooks

  • HTTPSのサイトからのダウンロード方法

    HTTPSのサイトにアクセスしてブラウザではなくテキストで表示させるにはどうすればいいのでしょうか? 通常のHTTPのサイトからは下記のコードで動作するようになりました。 これでHTTPSのサイトにアクセスしても返事が返ってきません。 今アクセスしようとしているページはまだユーザー名、パスワードが不用なページです。 ブラウザで表示させれば問題なく表示されます。 ご存知の方は教えて下さい。 [サンプルコード] Private Sub btnConnect_Click(ByVal sender As System.Object,_    ByVal e As System.EventArgs) Handles btnConnect.Click 'HttpWebRequestの作成 Dim strURL As String txtResponce.Text = "" txtResponce.Refresh() If Me.rbULR1.Checked Then strURL = txtURL1.Text Else strURL = txtURL2.Text End If Dim webreq As System.Net.HttpWebRequest = _ CType(System.Net.WebRequest.Create(strURL), _ System.Net.HttpWebRequest) 'サーバーからの応答を受信するためのHttpWebResponseを取得 Dim webres As System.Net.HttpWebResponse = _ CType(webreq.GetResponse(), System.Net.HttpWebResponse) '文字コードを指定する Dim enc As System.Text.Encoding = _ System.Text.Encoding.GetEncoding(932) '応答データを受信するためのStreamを取得 Dim st As System.IO.Stream = webres.GetResponseStream() Dim sr As New System.IO.StreamReader(st, enc) '受信して表示 Me.txtResponce.Text = sr.ReadToEnd() '閉じる sr.Close() End Sub

  • フォト蔵へアップロードできません(C#)

    フォト蔵へアップロードするとエラー400が出てしまいます。 何が原因なのでしょうか?原因を教えてください。 以下コード //フォト蔵へのアップロード(注意動きません)// //送信するファイルのパス filePath="C:\\Users\\Public\\Pictures\\Sample Pictures\\test.jpg"; //送信先のURL string url1 = "http://api.photozou.jp/rest/photo_add"; //文字コード System.Text.Encoding enc = System.Text.Encoding.GetEncoding("UTF-8"); //WebRequestの作成 System.Net.HttpWebRequest req = (System.Net.HttpWebRequest) System.Net.WebRequest.Create(url1); //メソッドにPOSTを指定 req.Method = "POST"; //ベーシック認証宣言、アカウントとパスワード req.PreAuthenticate = true; NetworkCredential network = new NetworkCredential("mailaddress@hoge.com", "password"); req.Credentials = network; //ヘッダを設定 req.Headers.Add("album_id", "1234567"); //ContentTypeを設定 req.ContentType = "image/jpeg"; //POST送信するデータを作成 System.IO.FileStream fs = new System.IO.FileStream( filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read); //POST送信するデータの長さを指定 req.ContentLength = fs.Length; //データをPOST送信するためのStreamを取得 System.IO.Stream reqStream = req.GetRequestStream(); //ファイルの内容を送信 byte[] readData = new byte[0x1000]; int readSize = 0; while (true) { readSize = fs.Read(readData, 0, readData.Length); if (readSize == 0) break; reqStream.Write(readData, 0, readSize); } fs.Close(); reqStream.Close(); //サーバーからの応答を受信するためのWebResponseを取得 System.Net.HttpWebResponse res = (System.Net.HttpWebResponse) req.GetResponse(); //応答データを受信するためのStreamを取得 System.IO.Stream resStream = res.GetResponseStream(); //受信 System.IO.StreamReader sr = new System.IO.StreamReader(resStream, enc); //閉じる sr.Close();

  • [C#]FTPでの複数のファイルのアップロード

    ネットで調べたところ1つのファイルであれば、 下記の記述でアップロードできることがわかったのですが、 別々のフォルダにあるにファイルを複数同時にアップロードするプログラムがわかりません。 どなたかご教示ください。よろしくお願いいたします。 using System; using System.Net; using System.IO; class FtpWebPut {  static void Main()  {   string uri = "ftp://servername/Upload/secret.png";   string myFile = "tmp.png";   WebRequest req = WebRequest.Create(uri);   req.Credentials = new NetworkCredential("user01", "mypassword");   req.Method = WebRequestMethods.Ftp.UploadFile;   using (Stream st = req.GetRequestStream())   using (FileStream fs = new FileStream(myFile, FileMode.Open))   {    Byte[] buf = new Byte[1024];    int count = 0;    do    {     count = fs.Read(buf, 0, buf.Length);     st.Write(buf, 0, count);    }    while (count != 0);   }  } }

  • FTPサーバーからのファイルコピー

    勉強させてください。 vb2010.net win764bit FTPサーバーにアクセスし、FTPサーバーにあるCSVファイルをすべて 指定のフォルダにコピーしたいのです。 http://dobon.net/vb/dotnet/internet/ftpwebrequest.html#downloadfile を参考に作成しましたがうまくいきません。 1, Cドライブにコピーしたいのですが下記部分でアクセスに拒否されましたと  エラーが発生します。  Dim fs As New System.IO.FileStream( _ downFile, System.IO.FileMode.Create, System.IO.FileAccess.Write)  フォルダの設定をPrivate Const PATH_Folder = " C:\DATA"から  Private Const PATH_Folder = " \DATA"に変更するとサーバー上にアクセス(ファイルの書き込み)  が行われます。(プログラムの保存先が影響?)  指定したローカルにコピーするにはどうしららよいでしょうか。 2,1でサーバー上にファイルの書き込みができたのですが、FTPサーバーにあるCSVのデータの内容を  書くみたいでコピーできませんでした。  fs.Write(buffer, 0, readSize)をfs.CopyTo()に変更すればいいのではないかとおもい変更してみましたが、  fs.CopyTo(ここがわからない)が理解できずに動作しません。 アドバイスよろしくお願いいたします。 Imports System.Net Imports System.IO Module Module1 'FTP用host Private Const FTP_HOST = "ftp://TEST" 'FTP用USER Private Const FTP_USER = "ftpuser" 'FTP用PASSWORD Private Const FTP_PASS = "ftppass" 'FTPファイルコピー先フォルダ Private Const PATH_Folder = " C:\DATA" Private Function FTPDownLoad() As Boolean FTPDownLoad = False 'Try 'ダウンロードするファイルのURI Dim u As New Uri(FTP_HOST) 'ダウンロードしたファイルの保存先 Dim downFile As String = PATH_Folde Sub Main() '----------------------------- '-- FTP データ取得 '----------------------------- If FTPDownLoad() = False Then body = "FTPからのデータダウンロードに失敗しました。" + vbCrLf + sys_date & sys_time Exit Sub End If Private Function FTPDownLoad() As Boolean FTPDownLoad = False 'Try 'ダウンロードするファイルのURI Dim u As New Uri(FTP_HOST) 'ダウンロードしたファイルの保存先 Dim downFile As String = Palet_PATH_Folder 'FtpWebRequestの作成 Dim ftpReq As System.Net.FtpWebRequest = _ CType(System.Net.WebRequest.Create(u), System.Net.FtpWebRequest) 'ログインユーザー名とパスワードを設定 ftpReq.Credentials = New System.Net.NetworkCredential(FTP_USER, FTP_PASS) 'MethodにWebRequestMethods.Ftp.DownloadFile("RETR")を設定 'ftpReq.Method = System.Net.WebRequestMethods.Ftp.DownloadFile ftpReq.Method = System.Net.WebRequestMethods.Ftp.ListDirectoryDetails '要求の完了後に接続を閉じる ftpReq.KeepAlive = False 'ASCIIモードで転送する ftpReq.UseBinary = False 'PASSIVEモードを無効にする ftpReq.UsePassive = False 'FtpWebResponseを取得 Dim ftpRes As System.Net.FtpWebResponse = _ CType(ftpReq.GetResponse(), System.Net.FtpWebResponse) 'ファイルをダウンロードするためのStreamを取得 Dim resStrm As System.IO.Stream = ftpRes.GetResponseStream() 'ダウンロードしたファイルを書き込むためのFileStreamを作成 Dim fs As New System.IO.FileStream( _ downFile, System.IO.FileMode.Create, System.IO.FileAccess.Write) 'ダウンロードしたデータを書き込む Dim buffer(1023) As Byte While True Dim readSize As Integer = resStrm.Read(buffer, 0, buffer.Length) If readSize = 0 Then Exit While End If fs.Write(buffer, 0, readSize) End While fs.Close() resStrm.Close() 'FTPサーバーから送信されたステータスを表示 Console.WriteLine("{0}: {1}", ftpRes.StatusCode, ftpRes.StatusDescription) '閉じる ftpRes.Close() 'Catch ex As Exception ' MsgBox(ex.Message) ' Exit Function 'End Try FTPDownLoad = True End Function END sub

  • C#でHP上の特定データを自動更新で抽出したい

    ブラウザを立ち上げることなくHPに自動ログイン後、特定の表示データを抽出してリアルタイムに更新表示させたい(ブラウザでは更新ボタンのクリックが必要)。 ニコニコ動画の自動ログイン方法が公開されていますのでそれを真似て下記のプログラムを作成し、見かけ上は正常に動作していますが、これって「GetHtml」を呼ぶ度にログイン → ログアウトを繰り返すのでしょうか? もし、そうであればそれの回避方法を教えて頂けないでしょうか。(.Close()を呼ばないとか?) また、その確認方法があれば併せてお願いします。 /// ログイン (起動時1回のみ呼び出し) public bool LogIn() {  Hashtable hash = new Hashtable();  hash["username"] = "name";  hash["password"] = "123";  hash["Login"] = "login";  string s_param = "";  foreach (string s in hash.Keys)  {  s_param += string.Format("{0}={1}&", s, hash[s]);  }  HttpPost("Https", s_param); } /// POST送信 public void HttpPost(string s_url, string s_param) {  httpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(s_url);  CookieContainer cookieContainer = new CookieContainer();  httpWebRequest.CookieContainer = cookieContainer;  httpWebRequest.ContentType = "application/x-www-form-urlencoded";  byte[] data = Encoding.ASCII.GetBytes(s_param);  httpWebRequest.ContentLength = data.Length;  httpWebRequest.Method = "Post";  Stream reqStream = httpWebRequest.GetRequestStream();  reqStream.Write(data, 0, data.Length);  reqStream.Close();  WebResponse webResponse = httpWebRequest.GetResponse();  Stream resStream = webResponse.GetResponseStream();  encoder = Encoding.GetEncoding("Shift_JIS");  StreamReader streamReader = new StreamReader(resStream, encoder);  spHtml = streamReader.ReadToEnd();  streamReader.Close();  webResponse.Close(); } /// HTML受信(タイマーイベントで常時呼び出し) private string GetHtml(string s_url) {  httpWebRequest = (HttpWebRequest)WebRequest.Create(s_url);  httpWebRequest.CookieContainer = cookieContainer;  webResponse = httpWebRequest.GetResponse();  Stream resStream = webResponse.GetResponseStream();  StreamReader streamReader = new StreamReader(resStream, encoder);  string Html = streamReader.ReadToEnd();  streamReader.Close();  resStream.Close();  return Html; }

  • サイトのデータ(HTML)を取得

    C#で WebRequest webreq = (HttpWebRequest)WebRequest.Create(strURL); webreq.Timeout = 10000; HttpWebResponse webres = (HttpWebResponse)webreq.GetResponse(); でサイトのデータ(HTML)を取得しているのですが、 サイトによっては1ページ全部取得できない場合があります。 しかしブラウザで見ると全部表示され、 そのソースをみても全部表示されています。 なぜC#のRequestで取得した場合には、 ソースが途切れる場合があるのでしょうか? 取得中タイムとかの設定があるのでしょうか? よろしくお願いします。

  • C#でIEの操作ができないページの操作方法

    C#でIEを操作しようとしているのですが、HTMLを取得する際にエラーが出てしまします。なぜでしょうか? yahooなどのサイトのHTMLは取得できるのですが、実際にhtmlを取得したいサイトは「型 'System.Net.WebException' のハンドルされていない例外が System.dll で発生しました 追加情報:接続が切断されました: 送信時に、予期しないエラーが発生しました。」とエラーがでます。 HTMLが取得できないサイトがあるのでしょうか? その時にどうすればHTMLを取得し、操作できるのかその方法を教えてください。 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.IO; using System.Linq; using System.Net; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace WindowsFormsApplication2 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { Encoding enc = Encoding.GetEncoding("Shift_JIS"); string url = "https://www.yahoo.co.jp/"; WebRequest req = WebRequest.Create(url); WebResponse res = req.GetResponse(); Stream st = res.GetResponseStream(); StreamReader sr = new StreamReader(st, enc); string html = sr.ReadToEnd(); sr.Close(); st.Close(); Console.WriteLine(html); } } }

  • VB ファイル保存

    XMLファイルに設定情報を保存仕様としているのですが,ある所でエラーが出てうまく走りません. 下記がそのプログラムになりますが,XMLファイルに保存のコメント下の所でエラーになります. エラーの内容は「保護レベルの設定が原因で'windowsApplication1.Form2'にアクセスできません」 です. どなたかご教示のほどよろしくお願いいたします. Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click 'ファイルが存在しない場合に新規にブランクファイルを作成する 'XMLファイルパス Dim xmlFile1 As String = "C:\OBS_Setting.xml" Dim hStream As System.IO.FileStream 'XMLファイルが存在するか確認 If Dir(xmlFile1) = "" Then ' 指定したパスのファイルを作成する hStream = System.IO.File.Create(xmlFile1) ' hStream が破棄されることを保証するために Try ~ Finally を使用する Try ' hStream が閉じられることを保証するために Try ~ Finally を使用する Try Finally ' 作成時に返される FileStream を利用して閉じる If Not hStream Is Nothing Then hStream.Close() End If End Try Finally ' hStream を破棄する If Not hStream Is Nothing Then Dim cDisposable As System.IDisposable = hStream cDisposable.Dispose() End If End Try End If 'XMLファイルに設定データを保存する Dim Area As String = ComboBox1.Text Dim State As String = ComboBox2.Text Dim City As String = ComboBox3.Text Dim BefY As String = ComboBox4.SelectedIndex Dim AftY As String = ComboBox5.SelectedIndex Dim BefM As String = ComboBox6.SelectedIndex Dim AftM As String = ComboBox7.SelectedIndex '保存するオブジェクトの配列を作成 '保存するオブジェクトの配列を作成 Dim myClasses(6) As SampleClass myClasses(0) = New SampleClass() myClasses(0).Number = 0 myClasses(0).Message = Area myClasses(1) = New SampleClass() myClasses(1).Number = 1 myClasses(1).Message = State myClasses(2) = New SampleClass() myClasses(2).Number = 2 myClasses(2).Message = City myClasses(3) = New SampleClass() myClasses(3).Number = 3 myClasses(3).Message = BefY myClasses(4) = New SampleClass() myClasses(4).Number = 4 myClasses(4).Message = AftY myClasses(5) = New SampleClass() myClasses(5).Number = 5 myClasses(5).Message = BefM myClasses(6) = New SampleClass() myClasses(6).Number = 6 myClasses(6).Message = AftM 'XMLファイルに保存 Dim serializer As New System.Xml.Serialization.XmlSerializer(GetType(SampleClass())) Dim fs1 As New IO.FileStream(xmlFile1, IO.FileMode.Create) serializer.Serialize(fs1, myClasses) fs1.Close() End Sub 'XMLファイルに保存するオブジェクトのためのクラス Public Class SampleClass Public Number As Integer Public Message As String End Class