インターネット上からファイルをダウンロードする方法はいくつかある。ここではwininetのInternetOpen、InternetOpenUrl、InternetReadFileを利用した。
#include "wininet.h"
#pragma comment(lib,"wininet.lib")
//
// ファイルのダウンロード
//
// FTP/HTTP両方に対応する。
// FTPの場合は「ret = DownloadFile(_T("ftp://userid:password@usefullcode.net/home/user/htdocs/index.html"),_T("index.html"));」
// のようにしてユーザーアカウントとパスワードを設定する
//
bool DownloadFile(LPCTSTR pszURL,LPCTSTR pszLocalFile,DWORD dwBuffSize=1024)
{
TCHAR pszHeader[] = _T("Accept: */*\r\n\r\n");
BOOL ret;
DWORD dwReadSize;
DWORD dwWrittenSize;
BYTE* pcbBuff;
HINTERNET hInternet;
HINTERNET hConnect;
HANDLE hFile;
hInternet = ::InternetOpen(NULL,INTERNET_OPEN_TYPE_PRECONFIG,NULL,NULL,0);
if(hInternet == NULL)
return false;
hConnect = ::InternetOpenUrl(hInternet,pszURL,pszHeader,-1,INTERNET_FLAG_DONT_CACHE,0);
pcbBuff = new BYTE[dwBuffSize];
if(hConnect == NULL || pcbBuff == NULL)
{
if(hConnect)
::InternetCloseHandle(hConnect);
::InternetCloseHandle(hInternet);
if(pcbBuff)
delete pcbBuff;
return false;
}
//保存先のファイルを作る。ファイルがあった場合は失敗
hFile = ::CreateFile(pszLocalFile,GENERIC_WRITE,0,NULL,CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
ret = (hFile == INVALID_HANDLE_VALUE) ? FALSE : TRUE;
while(ret)
{
::Sleep(0);
ret = ::InternetReadFile(hConnect,pcbBuff,dwBuffSize,&dwReadSize);
if(ret == FALSE || dwReadSize == 0)
break;
ret = ::WriteFile(hFile,pcbBuff,dwReadSize,&dwWrittenSize,NULL);
}
if(hFile != INVALID_HANDLE_VALUE)
{
::CloseHandle(hFile);
//失敗時は作成したファイルを削除
if(ret == FALSE)
::DeleteFile(pszLocalFile);
}
::InternetCloseHandle(hConnect);
::InternetCloseHandle(hInternet);
delete pcbBuff;
return ret ? true : false;
}
void Test(void)
{
bool ret;
ret = DownloadFile(_T("http://www.google.co.jp/"),_T("google.html"));
if(ret)
::MessageBox(NULL,_T("ダウンロードしました"),_T(""),MB_OK);
else
::MessageBox(NULL,_T("失敗しました"),_T(""),MB_OK);
}
