C#プログラミングTips

Webページのダウンロード(2)

デジタルアドバンテージ
2002/03/27


WebRequestクラスとWebResponseクラスの構造

 前出のサンプル・プログラム(webreq.cs)では、アクセス対象としてInsider.NETのトップページへのURLを埋め込んでいたが、実はこのURL部分で次のように“fileスキーム”を使用したURI(Uniform Resource Identifiers)によりローカル・ファイルを指定してもプログラムは同様に動作する(WebRequestクラスは、これ以外にもhttpsスキームにも対応している)。

10: string uri = "file:///c:/boot.ini";

 例えばこれは、ローカル・マシンにある“c:\boot.ini”を指し示している。サンプル・プログラム(webreq.cs)において、この行のみを修正して実行した例が次の画面だ。

ローカル・ファイルをアクセスするように変更したサンプル・プログラムの実行結果
  レスポンス・ヘッダの内容
  c:\boot.iniの内容

 “http://〜”によるWebページのアクセスも、“file://〜”によるローカル・ファイルのアクセスも同じURIの書式となっているが、プロトコル・レベルでのアクセス手順はまったく異なるものだ。にもかかわらず、WebRequestクラスのGetResponseメソッドや、WebResponseクラスのGetResponseStreamメソッドが同様に使用できるのは、それらのクラスがそれぞれのプロトコルに個別に対応しているからではない。

 次の図に示すように、実はWebRequestクラスとWebResponseクラスは抽象クラスである。そしてそれらの派生クラスが具体的なプロトコルを実装している。サンプル・プログラムの先頭で、WebRequest.Createメソッドにより作成されるオブジェクトは、実際にはこれら派生クラスのインスタンスとなっているのである。つまり、WebRequest.Createメソッドに渡すパラメータが“http://〜”ならばHttpWebRequestクラスの、“file://〜”であればFileWebRequestクラスのインスタンスが水面下で作成されている(それぞれのインスタンスは親クラスであるWebRequestのインスタンスとして参照できる)。同様に、GetResponseメソッドにより得られるインスタンスは、実際にはHttpWebResponseクラスFileWebResponseクラスのオブジェクトとなっている。

WebRequest、WebResponse抽象クラスと、その派生クラス

 このようなクラス構造をとっている利点の1つは、ここで示したように異なるスキームに対しても、共通した一連のプログラミング・インターフェイスを提供できることだ。プログラマーは各プロトコルに固有のアクセス手順を意識せずに、インターネット上のリソースを使用したプログラムを作成できる。

 もちろん各プロトコルに共通でない固有な機能は存在する。例えばHttpWebResponseクラスには、レスポンス・メッセージを受け取ったときの応答ステータスを取得するためのStatusCodeプロパティがある。このようなプロパティにアクセスするためには、次のようにオブジェクトをHttpWebResponse型へキャストする必要がある。

if (res is HttpWebResponse) {
  HttpWebResponse httpres = (HttpWebResponse)res;
  Console.WriteLine(httpres.StatusCode);
}
HttpWebResponseクラス独自のStatusCodeプロパティへのアクセス

 ほかのメリットとしては、ユーザーによる別のスキームの追加が容易なことも挙げられる。本題からは少し離れてしまうが、最後に別スキームへの対応例として、ftpスキームを追加してみる。

ftpスキームへの対応

 WebRequestクラスとWebResponseクラスによるftpのアクセス(“ftp://〜”によるアクセス)は残念ながら標準のクラス・ライブラリでは提供されていない。このような場合、WebRequestクラスとWebResponseクラスをそれぞれ継承したクラス(恐らくクラス名はFtpWebRequestとFtpWebResponseになるだろう)を作成し、FTPプロトコルを実装したGetResponseメソッドなどをオーバーライドして記述しなければならない。

 ここでは、Microsoftが運営するGotDotNetで公開されているサンプル・プログラムを利用する。GotDotNet User Uploads Searchのページで[Keyword Search]に“ftp”と入力して検索すると見つかる「FTP Pluggable Protocol Sample」がそのサンプル・プログラムだ。

 ダウンロードできるftpclient.zipには2つのファイルが含まれるが、このうちftpwebrequest.csがFTPプロトコルを実装しているファイルだ。これは.NET Frameworkベータ2で作成されたものだが、製品版でも取りあえず動作するようである。このファイルと、先ほどのサンプル・プログラムを一部修正した以下のコード(ftpreq.cs)をリンクしてコンパイルする。コンパイルは次のようにして行う。これによりftpreq.exeが作成される。

csc /out:ftpreq.exe ftpwebrequest.cs ftpreq.cs

 1: // ftpreq.cs
 2:
 3: using System;
 4: using System.IO;
 5: using System.Text;
 6: using System.Net;
 7:
 8: public class FtpReqRes {
 9:   public static void Main() {
10:     string uri = "ftp://ftp.microsoft.com/developr/readme.txt";
11:
12:     // 派生クラスの登録
13:     //
14:     FtpRequestCreator Creator = new FtpRequestCreator();
15:     WebRequest.RegisterPrefix("ftp:", Creator);
16:
17:     WebRequest  req = WebRequest.Create(uri);
18:     req.Method = "GET";
19:     WebResponse res = req.GetResponse();
20:
21:     // コンテンツの表示
22:     //
23:     Stream       st = res.GetResponseStream();
24:     StreamReader sr = new StreamReader(st,
25:                         Encoding.GetEncoding("Shift_JIS" ));
26:     Console.WriteLine(sr.ReadToEnd());
27:
28:     sr.Close();
29:     st.Close();
30:   }
31: }
GotDotNetのサンプル・コードを利用して、ftpサイトにあるファイルを表示するように修正したプログラムftpreq.cs
ftpreq.csのダウンロード

 このプログラムでは、次のURIで示されるMicrosoftのFTPサイトにあるreadme.txtファイルの内容を画面に表示する。

 ftpwebrequest.csでは、ヘッダの取得に関するメソッドが実装されていなかったため、ヘッダ情報を表示しているコードは削除した。これ以外に、1つ前に示したサンプル・プログラム(webreq.cs)から次の2個所を変更している。

 1つは、WebRequestクラスから派生しているFtpWebRequestクラス(ftpwebrequest.csで実装されている)を、ftpスキームのプリフィックス“ftp:”とともに、WebRequest.RegisterPrefixメソッドによりあらかじめ登録している(14〜15行目)。

 もう1つは、WebRequestのMethodプロパティを“GET”に設定している個所だ(18行目)。ftpwebrequest.csでは、FTPプロトコルで使用されるコマンドとして、GET、PUT、LIST、CD、PWDを実装しているが、これらのコマンドのいずれか1つをこのMethodプロパティで指定して使用する。このプロパティの値はデフォルトでは“DIR”となっているため、ファイルの内容を取得するためにはこれを“GET”に変更してからGetResponseメソッドを呼び出す必要がある。End of Article

関連リンク
GotDotNet User Uploads Searchのページ
 
 

 INDEX
  C#プログラミングTips
     Webページのダウンロード(1)
   Webページのダウンロード(2)
 
「C#プログラミングTips」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間