WebRequest、WebResponseクラスを使ってファイルをダウンロードし表示するWebRequest、WebResponseクラスを使ってインターネットのデータにアクセスする方法を紹介します。こちらやこちらで紹介したようなWebClientクラスでは、内部でWebRequest、WebResponseクラスを使用しています。よってここで紹介する方法を使用すれば、より柔軟で高度なことができるようになります。 次の例では、Yahoo! Japan のトップページのソースを表示しています。 'HttpWebRequestの作成 Dim webreq As System.Net.HttpWebRequest = _ CType(System.Net.WebRequest.Create("http://www.yahoo.co.jp"), _ System.Net.HttpWebRequest) 'または、 'Dim webreq As System.Net.WebRequest = _ ' System.Net.WebRequest.Create("http://www.yahoo.co.jp") 'サーバーからの応答を受信するためのHttpWebResponseを取得 Dim webres As System.Net.HttpWebResponse = _ CType(webreq.GetResponse(), System.Net.HttpWebResponse) 'または、 'Dim webres As System.Net.WebResponse = webreq.GetResponse() '文字コード(EUC)を指定する Dim enc As System.Text.Encoding = _ System.Text.Encoding.GetEncoding("euc-jp") '応答データを受信するためのStreamを取得 Dim st As System.IO.Stream = webres.GetResponseStream() Dim sr As New System.IO.StreamReader(st, enc) '受信して表示 Dim html As String = sr.ReadToEnd() Console.WriteLine(html) '閉じる 'webres.Close()でもよい sr.Close() //HttpWebRequestの作成 System.Net.HttpWebRequest webreq = (System.Net.HttpWebRequest) System.Net.WebRequest.Create("http://www.yahoo.co.jp"); //または、 //System.Net.WebRequest webreq = // System.Net.WebRequest.Create("http://www.yahoo.co.jp"); //サーバーからの応答を受信するためのHttpWebResponseを取得 System.Net.HttpWebResponse webres = (System.Net.HttpWebResponse) webreq.GetResponse(); //または、 //System.Net.WebResponse webres = webreq.GetResponse(); //文字コード(EUC)を指定する System.Text.Encoding enc = System.Text.Encoding.GetEncoding("euc-jp"); //応答データを受信するためのStreamを取得 System.IO.Stream st = webres.GetResponseStream(); System.IO.StreamReader sr = new System.IO.StreamReader(st, enc); //受信して表示 string html = sr.ReadToEnd(); Console.WriteLine(html); //閉じる //webres.Close()でもよい sr.Close();
補足:文字コードを指定しているEncodingクラスについては、こちらをご覧ください。
WebRequestインスタンスは、WebRequest.Createメソッドで作成します。このとき、指定されたURIによって、適当なWebRequestの派生クラスのインスタンスが返されます。例えば、上記のようにURIのスキームがhttp://またはhttps://の場合は、HttpWebRequestインスタンスを返します。また、file://の場合は、FileWebRequestを返します。さらに、.NET Framework 2.0以降では、ftp://の場合、FtpWebRequestを返します。 非同期でダウンロードする上記の方法は同期処理のため、受信が完了するまでの間、フリーズしたようになります。これを解決するには、スレッド化するか、非同期処理を行います。ここでは非同期処理の方法について、具体的な例を紹介します。 非同期処理では、まずWebRequest.BeginGetResponseメソッドにより、サーバーからの応答を要求し、待機します。さらに、データを非同期で受信するために、Stream.BeginReadメソッドで読み込みを開始します。 次に示すコンソールアプリケーションのサンプルは、「http://www.yahoo.co.jp」からデータを受信し、表示するものです。非同期要求では自分でタイムアウト処理を行う必要がありますが、このサンプルでは行っていません(WebRequest.TimeoutプロパティはBeginGetResponseメソッドでは無視されます)。詳しくは、下の「参考」をご覧ください。 このような非同期処理を行うには、マルチスレッドプログラミングの知識が必要です。詳しくは、こちらをご覧ください。 Imports System Class MainClass '受信したデータを入れておくMemoryStream Private Shared requestData As System.IO.MemoryStream '受信したデータを入れるバッファ Private Shared bufferData() As Byte 'エントリポイント Public Shared Sub Main() 'HttpWebRequestの作成 Dim webreq As System.Net.HttpWebRequest = _ CType(System.Net.WebRequest.Create( _ "http://www.yahoo.co.jp"), _ System.Net.HttpWebRequest) '非同期要求を開始 '状態オブジェクトとしてHttpWebRequestをわたす Dim r As IAsyncResult = _ CType(webreq.BeginGetResponse( _ New AsyncCallback(AddressOf ResponseCallback), webreq), _ IAsyncResult) '待機する Console.ReadLine() End Sub '非同期要求が終了した時に呼び出されるコールバックメソッド Private Shared Sub ResponseCallback(ByVal ar As IAsyncResult) '状態オブジェクトとしてわたされたHttpWebRequestを取得 Dim webreq As System.Net.HttpWebRequest = _ CType(ar.AsyncState, System.Net.HttpWebRequest) '非同期要求を終了 Dim webres As System.Net.HttpWebResponse = _ CType(webreq.EndGetResponse(ar), System.Net.HttpWebResponse) 'ストリームを取得 Dim st As System.IO.Stream = webres.GetResponseStream() 'データを読み込むための準備をする requestData = New System.IO.MemoryStream bufferData = New Byte(1024) {} '非同期でデータの読み込みを開始 '状態オブジェクトとしてStreamをわたす Dim r As IAsyncResult = _ CType(st.BeginRead(bufferData, 0, bufferData.Length, _ New AsyncCallback(AddressOf ReadCallback), st), _ IAsyncResult) End Sub '非同期読み込み完了時に呼び出されるコールバックメソッド Private Shared Sub ReadCallback(ByVal ar As IAsyncResult) '状態オブジェクトとしてわたされたStreamを取得 Dim st As System.IO.Stream = _ CType(ar.AsyncState, System.IO.Stream) 'データを読み込む Dim readSize As Integer = st.EndRead(ar) If readSize > 0 Then 'データが読み込めた時 '読み込んだデータをMemoryStreamに保存する requestData.Write(bufferData, 0, readSize) '再び非同期でデータを読み込む Dim r As IAsyncResult = _ CType(st.BeginRead(bufferData, 0, bufferData.Length, _ New AsyncCallback(AddressOf ReadCallback), st), _ IAsyncResult) Else 'データの読み込みが終了した時 'データをデコードして表示する Dim enc As System.Text.Encoding = _ System.Text.Encoding.GetEncoding(51932) Console.Write(enc.GetString(requestData.ToArray())) '閉じる st.Close() requestData.Close() End If End Sub End Class using System; class MainClass { //受信したデータを入れておくMemoryStream private static System.IO.MemoryStream requestData; //受信したデータを入れるバッファ private static byte[] bufferData; //エントリポイント public static void Main() { //HttpWebRequestの作成 System.Net.HttpWebRequest webreq = (System.Net.HttpWebRequest) System.Net.WebRequest.Create("http://www.yahoo.co.jp"); //非同期要求を開始 //状態オブジェクトとしてHttpWebRequestをわたす IAsyncResult r = (IAsyncResult) webreq.BeginGetResponse( new AsyncCallback(ResponseCallback), webreq); //待機する Console.ReadLine(); } //非同期要求が終了した時に呼び出されるコールバックメソッド private static void ResponseCallback(IAsyncResult ar) { //状態オブジェクトとしてわたされたHttpWebRequestを取得 System.Net.HttpWebRequest webreq = (System.Net.HttpWebRequest) ar.AsyncState; //非同期要求を終了 System.Net.HttpWebResponse webres = (System.Net.HttpWebResponse) webreq.EndGetResponse(ar); //ストリームを取得 System.IO.Stream st = webres.GetResponseStream(); //データを読み込むための準備をする requestData = new System.IO.MemoryStream(); bufferData = new byte[1024]; //非同期でデータの読み込みを開始 //状態オブジェクトとしてStreamをわたす IAsyncResult r = (IAsyncResult) st.BeginRead( bufferData, 0, bufferData.Length, new AsyncCallback(ReadCallback), st); } //非同期読み込み完了時に呼び出されるコールバックメソッド private static void ReadCallback(IAsyncResult ar) { //状態オブジェクトとしてわたされたStreamを取得 System.IO.Stream st = (System.IO.Stream) ar.AsyncState; //データを読み込む int readSize = st.EndRead(ar); if (readSize > 0) { //データが読み込めた時 //読み込んだデータをMemoryStreamに保存する requestData.Write(bufferData, 0, readSize); //再び非同期でデータを読み込む IAsyncResult r = (IAsyncResult) st.BeginRead( bufferData, 0, bufferData.Length, new AsyncCallback(ReadCallback), st); } else { //データの読み込みが終了した時 //データをデコードして表示する System.Text.Encoding enc = System.Text.Encoding.GetEncoding(51932); Console.Write(enc.GetString(requestData.ToArray())); //閉じる st.Close(); requestData.Close(); } } }
注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。
|
|
Copyright(C) DOBON!. All rights reserved.
|