WinInetによるインターネット上ファイルの読み込み

WinInet APIを使うと、httpFTPを利用してインターネット上のファイルにアクセスするプログラムを簡単に書く事が出来ます。ネットワークのプログラミングは通常ソケットを使って何度もサーバーとやり取りをしたりとかなり面倒ですが、WinInet APIを使えば面倒な部分はWinInet APIで処理してくれるので、かなり楽が出来るわけです。

特に、httpでファイルを読み込む処理はほとんどローカルのファイルと同じような感覚で出来ます。今回は、WinInet APIを使ってhttpによるファイル取得を試してみましょう。

WinInet APIによるhttpアクセス

WinInet APIhttpを使ってファイルを読み込む処理は、

  1. WinInetのハンドルを作成
  2. 1のハンドルを使ってURLを開く
  3. 開いたURLからファイルをバッファに読み込む

という流れになります。ほとんどローカルのファイル読み込みと同じですね。実際、処理としてはきわめて簡単で、注意すべき点はファイルサイズとバッファの容量くらいでしょう。

まず、ファイルを読み込むバッファを作っておきましょう。今回は、読み込み用のバッファとして1024バイトのバッファlpszBufを確保しておきます。

  lpszBuf=(LPTSTR)GlobalAlloc(GPTR,1024);

続いて、WinInet APIのハンドルhInetを作成。ハンドルの作成はInternetOpen()に各種のフラグなどを指定して行います。

  /* ハンドル作成 */
  hInet=InternetOpen("TEST",INTERNET_OPEN_TYPE_DIRECT,
        NULL,NULL,0);

最初の引数で指定した文字列は、httpアクセス時にサーバーにHTTP_USER_AGENTとして渡されます。

InternetOpen()は、URLを開くためのハンドルを返します。

取得したハンドルhInetをInternetOpenUrl()に渡して、URLhttp://www.sm.rim.or.jp/~shishido/src/httpt.txt(今回のプログラムソース)を開いてみましょう。

  /* URLオープン */
  hFile=InternetOpenUrl(hInet,
        "http://www.sm.rim.or.jp/~shishido/src/httpt.txt",
        NULL,0,INTERNET_FLAG_RELOAD,0);

これでサーバー上のファイルhttpt.txtを読み込むためのハンドルhFileが出来たので、ファイルをバッファに読み込みます。

  /* ファイル読み込み */
  InternetReadFile(hFile,lpszBuf,1023,&dwSize);

ファイルの読み込みは、InternetReadFile()にバッファのポインタとサイズを指定して行います。

ファイルの内容は、2番目の引数で指定したバッファに順次読み込まれますが、大きなファイルを読む時にはバッファのサイズ毎に分けて読む事になるようです。具体的には、ファイルの内容をバッファに読み込んでそれを別のバッファにコピーして内容を保存していく、という処理をファイルをすべて読み込むまで行う事になるでしょう。

ファイルの読み込みが完了したかどうかは、最後の引数に渡す変数を見ればわかります。この変数には実際に読み込んだバイト数が格納されますが、ファイルをすべて読み込んだ場合は0が格納されます。サイズが不明の大きなファイルを読み込む時には、dwSizeが0になるまでInternetReadFile()を呼び出してバッファにファイルの内容を取得し、保存用バッファに追記していく処理を行う必要があります。

今回は、先頭から最大1023バイトだけを読み込むようにしてみました(というか、ソースのサイズが1023バイト以下なので一度に読めます)。

ファイルを読み込んでバッファに格納し終わったら、アクセスに使ったハンドルを解放しましょう。

  /* 終了処理 */
  InternetCloseHandle(hFile);
  InternetCloseHandle(hInet);

WinInetでファイルを読み込むプログラム

今回のサンプルプログラムは、コンソールアプリケーションです。プログラムをビルドする時は、プロジェクトの設定でwininet.libをリンクしてください。

プログラムソース表示

インターネットに接続した状態で実行すると、今回のプログラムのソースファイルをネット上から取得し表示します。

WinInet APIでインターネット上のhttpサーバーにアクセスできるようになれば、情報の取得だけでなくCGIGETで引数を渡して情報を登録したりといろいろな事が出来そうですね。


プログラミング資料庫 > Windowsプログラミング研究室