キャッシュ (Windows インターネット)

WinINet 関数には、シンプルでありながら柔軟な組み込みのキャッシュ サポートがあります。 ネットワークから取得されたデータは、ハード ディスクにキャッシュされ、後続の要求に対して取得されます。 アプリケーションは、各要求のキャッシュを制御できます。 サーバーからの http 要求の場合、受信したほとんどのヘッダーもキャッシュされます。 キャッシュから http 要求が満たされると、キャッシュされたヘッダーも呼び出し元に返されます。 これにより、データがキャッシュまたはネットワークから送信されているかどうかに関係なく、データのダウンロードがシームレスになります。

永続的な URL キャッシュ関数を使用するときに目的の結果を得るには、アプリケーションでバッファーを適切に割り当てる必要があります。 詳細については、「バッファーの 使用」を参照してください。

応答処理中のキャッシュ動作

WinINet キャッシュは、RFC 2616 で説明されている HTTP キャッシュ制御ディレクティブに準拠しています。 キャッシュ制御ディレクティブとアプリケーション セット フラグによって、キャッシュされる可能性がある内容が決まります。ただし、WinINet は、次の条件に基づいて、実際にキャッシュされる内容を決定します。

  • WinINet では、HTTP 応答と FTP 応答のみがキャッシュされます。
  • キャッシュによって格納され、後続の要求への応答で使用できるのは、適切に動作する応答のみです。 適切に動作する応答は、正常に返される応答として定義されます。
  • 既定では、WinINet は、サーバーからのキャッシュ制御ディレクティブ、またはアプリケーション定義フラグによって応答がキャッシュされないことを明確に示す場合を除き、成功した応答をキャッシュします。
  • 一般に、上記の要件が満たされている場合、GET 動詞への応答はキャッシュされます。 PUT 動詞と POST 動詞に対する応答は、どのような状況でもキャッシュされません。
  • キャッシュがいっぱいの場合でも、項目はキャッシュされます。 追加された項目がサイズ制限を超えてキャッシュを配置すると、キャッシュ スカベンジャーがスケジュールされます。 既定では、アイテムがキャッシュに 10 分を超える状態を維持することは保証されません。 詳細については、以下の 「キャッシュ スカベンジャー 」セクションを参照してください。
  • Https は既定でキャッシュされます。 これは、アプリケーション定義のキャッシュ ディレクティブではオーバーライドできないグローバル設定によって管理されます。 グローバル設定をオーバーライドするには、コントロール パネルで [インターネット オプション] アプレットを選択し、[詳細設定] タブに移動します。[セキュリティ] セクションの [暗号化されたページをディスクに保存しない] ボックスをオンにします。

キャッシュ スカベンジャー

キャッシュ スカベンジャーは、キャッシュからアイテムを定期的にクリーンアップします。 項目がキャッシュに追加され、キャッシュがいっぱいの場合は、キャッシュに項目が追加され、キャッシュ スカベンジャーがスケジュールされます。 キャッシュ スカベンジャーが清掃のラウンドを完了し、キャッシュがキャッシュの制限に達していない場合、キャッシュに別の項目が追加されたときに、スカベンジャーは別のラウンドにスケジュールされます。 一般に、スカベンジャーは、追加された項目によってキャッシュがサイズ制限を超えたときにスケジュールされます。 既定では、キャッシュ制御ディレクティブで特に指定されていない限り、キャッシュの有効期間の最小時間は 10 分に設定されます。 キャッシュ スカベンジャーが開始されると、最も古い項目がキャッシュから最初に削除される保証はありません。

キャッシュは、同じユーザーのコンピューター上のすべての WinINet アプリケーション間で共有されます。 Windows Vista および Windows Server 2008 以降では、キャッシュ サイズはディスクのサイズの 1/32 に設定され、最小サイズは 8 MB、最大サイズは 50 MB です。

フラグを使用したキャッシュの制御

キャッシュ フラグを使用すると、アプリケーションはキャッシュを使用するタイミングと方法を制御できます。 これらのフラグは、単独で使用することも、インターネット上の情報やリソースにアクセスする関数の dwFlags パラメーターと組み合わせて使用することもできます。 既定では、関数はインターネットからダウンロードしたすべてのデータを格納します。

キャッシュを制御するには、次のフラグを使用できます。

説明
INTERNET_FLAG_CACHE_ASYNC このフラグは無効です。
INTERNET_FLAG_CACHE_IF_NET_FAIL ERROR_INTERNET_CONNECTION_RESETまたはERROR_INTERNET_CANNOT_CONNECT エラーが原因でリソースのネットワーク要求が失敗した場合は、キャッシュからリソース返します。 このフラグは、 HttpOpenRequest によって使用されます。
INTERNET_FLAG_DONT_CACHE ローカルまたはゲートウェイにデータをキャッシュしません。 優先値と同じ INTERNET_FLAG_NO_CACHE_WRITE
これがフォーム送信であることを示します。
INTERNET_FLAG_FROM_CACHEINTERNET_FLAG_FORMS_SUBMIT ネットワーク要求を行いません。 すべてのエンティティがキャッシュから返されます。 要求された項目がキャッシュにない場合は、ERROR_FILE_NOT_FOUNDなどの適切なエラーが返されます。 InternetOpen 関数のみがこのフラグを使用します。
INTERNET_FLAG_FWD_BACK 関数が、現在インターネット キャッシュ内にあるリソースのコピーを使用する必要があることを示します。 有効期限とリソースに関するその他の情報はチェックされません。 要求された項目がインターネット キャッシュに見つからない場合、システムはネットワーク上のリソースの検索を試みます。 この値は Microsoft Internet エクスプローラー 5 で導入され、インターネット エクスプローラーの [転送] ボタンと [戻る] ボタンの操作に関連付けられています。
INTERNET_FLAG_HYPERLINK 有効期限がなく、リソースがキャッシュに格納されたときに最終変更時刻が返されなかった場合は、強制的にリソースを再読み込みします。
INTERNET_FLAG_MAKE_PERSISTENT サポート対象から除外されました。
INTERNET_FLAG_MUST_CACHE_REQUEST ファイルをキャッシュできない場合は、一時ファイルを作成します。 これは、優先値 である INTERNET_FLAG_NEED_FILE と同じです。
INTERNET_FLAG_NEED_FILE ファイルをキャッシュできない場合は、一時ファイルを作成します。
INTERNET_FLAG_NO_CACHE_WRITE インターネットからダウンロードしたデータをキャッシュに格納する関数の試行を拒否します。 このフラグは、ダウンロードしたリソースをアプリケーションでローカルに保存しない場合に必要です。
INTERNET_FLAG_NO_UI Cookie ダイアログ ボックスを無効にします。 このフラグは、 HttpOpenRequestInternetOpenUrl (HTTP 要求のみ) で使用できます。
INTERNET_FLAG_OFFLINE アプリケーションがネットワークに要求を送信できないようにします。 すべての要求は、キャッシュに格納されているリソースを使用して解決されます。 リソースがキャッシュにない場合は、ERROR_FILE_NOT_FOUNDなどの適切なエラーが返されます。
INTERNET_FLAG_PRAGMA_NOCACHE キャッシュされたコピーがプロキシ上に存在する場合でも、配信元サーバーによって要求が強制的に解決されます。 InternetOpenUrl 関数 (HTTP および HTTPS 要求のみ) と HttpOpenRequest 関数は、このフラグを使用します。
INTERNET_FLAG_RELOAD 要求されたリソースをインターネットから直接取得するように関数を強制します。 ダウンロードされた情報はキャッシュに格納されます。
INTERNET_FLAG_RESYNCHRONIZE アプリケーションがインターネットからリソースの条件付きダウンロードを実行します。 キャッシュに格納されているバージョンが最新の場合、情報はキャッシュからダウンロードされます。 それ以外の場合、情報はサーバーから再読み込みされます。

 

永続キャッシュ関数

永続キャッシュ サービスを必要とするクライアントは、永続キャッシュ関数を使用して、アプリケーションが後で使用するためにローカル ファイル システムにデータを保存できるようにします。たとえば、帯域幅の低いリンクによってデータへのアクセスが制限されたり、アクセスがまったく使用できない場合などです。

キャッシュ関数は、永続的なキャッシュとオフライン参照を提供します。 INTERNET_FLAG_NO_CACHE_WRITE フラグでキャッシュが明示的に指定されていない限り、関数はネットワークからダウンロードされたすべてのデータをキャッシュします。 POST データに対する応答はキャッシュされません。

永続 URL キャッシュ関数の使用

次の永続的な URL キャッシュ関数を使用すると、アプリケーションはキャッシュに格納されている情報にアクセスして操作できます。

機能 Description
CommitUrlCacheEntryA キャッシュ ストレージ内の指定されたファイル内のデータをキャッシュし、指定された URL に関連付けます。
CommitUrlCacheEntryW キャッシュ ストレージ内の指定されたファイル内のデータをキャッシュし、指定された URL に関連付けます。
CreateUrlCacheEntry 要求されたキャッシュ ストレージを割り当て、ソース名に対応するキャッシュ エントリを保存するためのローカル ファイル名を作成します。
CreateUrlCacheGroup キャッシュ グループ ID を生成します。
DeleteUrlCacheEntry ファイルが存在する場合は、ソース名に関連付けられているファイルをキャッシュから削除します。
DeleteUrlCacheGroup キャッシュ インデックス ファイル内の GROUPID と関連付けられた状態を解放します。
FindCloseUrlCache 指定した列挙ハンドルを閉じます。
FindFirstUrlCacheEntry キャッシュの列挙を開始します。
FindFirstUrlCacheEntryEx キャッシュのフィルター処理された列挙を開始します。
FindNextUrlCacheEntry キャッシュ内の次のエントリを取得します。
FindNextUrlCacheEntryEx フィルター処理されたキャッシュ列挙の次のエントリを取得します。
GetUrlCacheEntryInfo キャッシュ エントリに関する情報を取得します。
GetUrlCacheEntryInfoEx HttpSendRequest によってオフライン モードで適用されるキャッシュリダイレクトを翻訳した後、URL を検索します。
ReadUrlCacheEntryStream RetrieveUrlCacheEntryStream を使用して開かれたストリームからキャッシュされたデータを読み取ります。
RetrieveUrlCacheEntryFile キャッシュからファイルの形式でキャッシュ エントリを取得します。
RetrieveUrlCacheEntryStream キャッシュ データにアクセスするための最も効率的で実装に依存しない方法を提供します。
SetUrlCacheEntryGroup キャッシュ グループのエントリを追加または削除します。
SetUrlCacheEntryInfo INTERNET_CACHE_ENTRY_INFO構造体の指定したメンバーを設定します。
UnlockUrlCacheEntryFile RetrieveUrlCacheEntryFile によってキャッシュから使用するためにファイルが取得されたときにロックされていたキャッシュ エントリのロックを解除します。
UnlockUrlCacheEntryStream RetrieveUrlCacheEntryStream を使用して取得されたストリームを閉じます。

 

キャッシュの列挙

FindFirstUrlCacheEntry 関数と FindNextUrlCacheEntry 関数は、キャッシュに格納されている情報を列挙します。 FindFirstUrlCacheEntry は、検索パターン、バッファー、バッファー サイズを取得して列挙を開始し、ハンドルを作成し、最初のキャッシュ エントリを返します。 FindNextUrlCacheEntry、FindFirstUrlCacheEntry によって作成されたハンドル、バッファー、バッファー サイズを受け取り、次のキャッシュ エントリを返します。

どちらの関数も、 バッファーにINTERNET_CACHE_ENTRY_INFO 構造体を格納します。 この構造体のサイズは、エントリごとに異なります。 いずれかの関数に渡されるバッファー サイズが不十分な場合、関数は失敗し、 GetLastError は ERROR_INSUFFICIENT_BUFFERを返します。 バッファー サイズ変数には、そのキャッシュ エントリを取得するために必要なバッファー サイズが含まれています。 バッファー サイズ変数によって示されるサイズのバッファーを割り当てる必要があり、関数を新しいバッファーで再度呼び出す必要があります。

INTERNET_CACHE_ENTRY_INFO構造体には、構造体のサイズ、キャッシュされた情報の URL、ローカル ファイル名、キャッシュ エントリの種類、使用回数、ヒット 率、サイズ、最終変更時刻、有効期限、最終アクセス、最終同期時刻、ヘッダー情報、ヘッダー情報サイズ、ファイル名拡張子が含まれます。

FindFirstUrlCacheEntry 関数は、検索パターン、INTERNET_CACHE_ENTRY_INFO構造体を格納するバッファー、およびバッファー サイズを受け取ります。 現在、すべてのキャッシュ エントリを返す既定の検索パターンのみが実装されています。

キャッシュを列挙した後、アプリケーションは FindCloseUrlCache を呼び出してキャッシュ列挙ハンドルを閉じる必要があります。

次の例では、リスト ボックスに各キャッシュ エントリの URL IDC_CacheList表示します。 初期バージョンの WinINet API ではキャッシュが適切に列挙されないため、MAX_CACHE_ENTRY_INFO_SIZEを使用して最初にバッファーを割り当てます。 以降のバージョンではキャッシュが正しく列挙され、キャッシュ サイズの制限はありません。 インターネット エクスプローラー 4.0 から WinINet API のバージョンを持つコンピューターで実行されるすべてのアプリケーションは、必要なサイズのバッファーを割り当てる必要があります。 詳細については、「バッファーの 使用」を参照してください。

int WINAPI EnumerateCacheOld(HWND hX)
{
    DWORD dwEntrySize;
    LPINTERNET_CACHE_ENTRY_INFO lpCacheEntry;
    DWORD MAX_CACHE_ENTRY_INFO_SIZE = 4096;
    HANDLE hCacheDir;
    int nCount=0;

    SendDlgItemMessage(hX,IDC_CacheList,LB_RESETCONTENT,0,0);
    
    SetCursor(LoadCursor(NULL,IDC_WAIT));

    dwEntrySize = MAX_CACHE_ENTRY_INFO_SIZE;
    lpCacheEntry = (LPINTERNET_CACHE_ENTRY_INFO) new char[dwEntrySize];
    lpCacheEntry->dwStructSize = dwEntrySize;

again:

    hCacheDir = FindFirstUrlCacheEntry(NULL,
                                       lpCacheEntry,
                                       &dwEntrySize);
    if (!hCacheDir)                                             
    {
        delete[]lpCacheEntry;
        switch(GetLastError())
        {
            case ERROR_NO_MORE_ITEMS: 
                TCHAR tempout[80];
                _stprintf_s(tempout, 
                            80,   
                            TEXT("The number of cache entries = %d \n"),
                            nCount);
                MessageBox(hX,tempout,TEXT("Cache Enumeration"),MB_OK);
                FindCloseUrlCache(hCacheDir);
                SetCursor(LoadCursor(NULL,IDC_ARROW));
                return TRUE;
                break;
            case ERROR_INSUFFICIENT_BUFFER:
                lpCacheEntry = (LPINTERNET_CACHE_ENTRY_INFO) 
                                new char[dwEntrySize];
                lpCacheEntry->dwStructSize = dwEntrySize;
                goto again;
                break;
            default:
                ErrorOut( hX,GetLastError(),
                          TEXT("FindNextUrlCacheEntry Init"));
                FindCloseUrlCache(hCacheDir);
                SetCursor(LoadCursor(NULL,IDC_ARROW));
                return FALSE;
        }
    }

    SendDlgItemMessage(hX,IDC_CacheList,LB_ADDSTRING,
                       0,(LPARAM)(lpCacheEntry->lpszSourceUrlName));
    nCount++;
    delete (lpCacheEntry);

    do 
    {
        dwEntrySize = MAX_CACHE_ENTRY_INFO_SIZE;
        lpCacheEntry = (LPINTERNET_CACHE_ENTRY_INFO) new char[dwEntrySize];
        lpCacheEntry->dwStructSize = dwEntrySize;

retry:
        if (!FindNextUrlCacheEntry(hCacheDir,
                                   lpCacheEntry, 
                                   &dwEntrySize))
        {
            delete[]lpCacheEntry;
            switch(GetLastError())
            {
                case ERROR_NO_MORE_ITEMS: 
                    TCHAR tempout[80];
                    _stprintf_s(tempout,
                                80,
                                TEXT("The number of cache entries = %d \n"),nCount);
                    MessageBox(hX,
                               tempout,
                               TEXT("Cache Enumeration"),MB_OK);
                    FindCloseUrlCache(hCacheDir);
                    return TRUE;
                    break;
                case ERROR_INSUFFICIENT_BUFFER:
                    lpCacheEntry = 
                             (LPINTERNET_CACHE_ENTRY_INFO) 
                              new char[dwEntrySize];
                    lpCacheEntry->dwStructSize = dwEntrySize;
                    goto retry;
                    break;
                default:
                    ErrorOut(hX,
                             GetLastError(),
                             TEXT("FindNextUrlCacheEntry Init"));
                    FindCloseUrlCache(hCacheDir);
                    return FALSE;
            }
        }

        SendDlgItemMessage(hX,
                           IDC_CacheList,LB_ADDSTRING,
                           0,
                          (LPARAM)(lpCacheEntry->lpszSourceUrlName));
        nCount++;
        delete[] lpCacheEntry;        
    }  while (TRUE);

    SetCursor(LoadCursor(NULL,IDC_ARROW));
    return TRUE;        
}

キャッシュ エントリ情報の取得

GetUrlCacheEntryInfo 関数を使用すると、指定した URL のINTERNET_CACHE_ENTRY_INFO構造を取得できます。 この構造体には、構造体のサイズ、キャッシュされた情報の URL、ローカル ファイル名、キャッシュ エントリの種類、使用回数、ヒット 率、サイズ、最終変更時刻、有効期限、最終アクセス、最終同期時刻、ヘッダー情報、ヘッダー情報サイズ、およびファイル名拡張子が含まれます。

GetUrlCacheEntryInfo は、URL、 INTERNET_CACHE_ENTRY_INFO 構造体のバッファー、およびバッファー サイズを受け入れます。 URL が見つかった場合、情報はバッファーにコピーされます。 それ以外の場合、関数は失敗し、 GetLastError は ERROR_FILE_NOT_FOUNDを返します。 バッファー サイズがキャッシュ エントリ情報を格納するのに十分でない場合、関数は失敗し、 GetLastError は ERROR_INSUFFICIENT_BUFFERを返します。 情報を取得するために必要なサイズは、バッファー サイズ変数に格納されます。

GetUrlCacheEntryInfo は URL 解析を行わないので、リソースがキャッシュされている場合でも、アンカー (#) を含む URL はキャッシュに見つかりません。 たとえば、URL が "https://example.com/example.htm#sample"が渡された場合、関数は"https://example.com/example.htm" の場合でもERROR_FILE_NOT_FOUNDを返します。はキャッシュ内にあります。

次の例では、指定した URL のキャッシュ エントリ情報を取得します。 その後、関数はヘッダー情報を [IDC_CacheDump ] 編集ボックスに表示します。

int WINAPI GetCacheEntryInfo(HWND hX,LPTSTR lpszUrl)
{
    DWORD dwEntrySize=0;
    LPINTERNET_CACHE_ENTRY_INFO lpCacheEntry;

    SetCursor(LoadCursor(NULL,IDC_WAIT));
    if (!GetUrlCacheEntryInfo(lpszUrl,NULL,&dwEntrySize))
    {
        if (GetLastError()!=ERROR_INSUFFICIENT_BUFFER)
        {
            ErrorOut(hX,GetLastError(),TEXT("GetUrlCacheEntryInfo"));
            SetCursor(LoadCursor(NULL,IDC_ARROW));
            return FALSE;
        }
        else
            lpCacheEntry = (LPINTERNET_CACHE_ENTRY_INFO) 
                            new char[dwEntrySize];
    }
    else
        return FALSE; // should not be successful w/ NULL buffer
                      // and 0 size

    if (!GetUrlCacheEntryInfo(lpszUrl,lpCacheEntry,&dwEntrySize))
    {
        ErrorOut(hX,GetLastError(),TEXT("GetUrlCacheEntryInfo"));
        SetCursor(LoadCursor(NULL,IDC_ARROW));
        return FALSE;
    }
    else
    {
        if ((lpCacheEntry->dwHeaderInfoSize)!=0)
        {
            LPSTR(lpCacheEntry->lpHeaderInfo)
                                [lpCacheEntry->dwHeaderInfoSize]=TEXT('\0');
            SetDlgItemText(hX,IDC_Headers,
                           lpCacheEntry->lpHeaderInfo);
        }
        else
        {
            SetDlgItemText(hX,IDC_Headers,TEXT("None"));
        }

        SetCursor(LoadCursor(NULL,IDC_ARROW));
        return TRUE;
    }
        
}

キャッシュ エントリの作成

アプリケーションは CreateUrlCacheEntry 関数と CommitUrlCacheEntry 関数を使用してキャッシュ エントリを作成します。

CreateUrlCacheEntry は、URL、予想されるファイル サイズ、ファイル名拡張子を受け入れます。 次に、 関数は、URL とファイル名拡張子に対応するキャッシュ エントリを保存するためのローカル ファイル名を作成します。

ローカル ファイル名を使用して、ローカル ファイルにデータを書き込みます。 データがローカル ファイルに書き込まれた後、アプリケーションは CommitUrlCacheEntry を呼び出す必要があります。

CommitUrlCacheEntry は、URL、ローカル ファイル名、有効期限、最終変更時刻、キャッシュ エントリの種類、ヘッダー情報、ヘッダー情報のサイズ、ファイル名拡張子を受け入れます。 関数は、キャッシュ ストレージで指定されたファイル内のデータをキャッシュし、指定された URL に関連付けます。

次の例では、 CreateUrlCacheEntry の以前の呼び出しによって作成されたローカル ファイル名を使用して、テキスト ボックス (IDC_LocalFile) に格納し、テキスト ボックス IDC_CacheDumpのテキストをキャッシュ エントリに格納します。 fopenfprintf、および fclose を使用してファイルにデータが書き込まれた後、CommitUrlCacheEntry を使用してエントリがコミットされます。

int WINAPI CommitEntry(HWND hX)
{
    LPTSTR lpszUrl, lpszExt, lpszFileName;
    LPTSTR lpszData,lpszSize;
    DWORD dwSize;
    DWORD dwEntryType=0;
    FILE *lpfCacheEntry;
    LPFILETIME lpdtmExpire, lpdtmLastModified;
    LPSYSTEMTIME lpdtmSysTime;
    errno_t err;

    if( SendDlgItemMessage(hX,IDC_RBNormal,BM_GETCHECK,0,0) )
    {
        dwEntryType = dwEntryType + NORMAL_CACHE_ENTRY;
    }
    else if( SendDlgItemMessage(hX,IDC_RBSticky, BM_GETCHECK,0,0) )
    {
        dwEntryType = dwEntryType + STICKY_CACHE_ENTRY;
    }
    else if(SendDlgItemMessage( hX,IDC_RBSparse, BM_GETCHECK,0,0) )
    {
        dwEntryType = dwEntryType + SPARSE_CACHE_ENTRY;
    }
 

    if( SendDlgItemMessage(hX,IDC_RBCookie, BM_GETCHECK,0,0))
    {
            dwEntryType = dwEntryType + COOKIE_CACHE_ENTRY;
    }
    else if( SendDlgItemMessage(hX,IDC_RBUrl, BM_GETCHECK,0,0) )
    {
        dwEntryType = dwEntryType + URLHISTORY_CACHE_ENTRY;
    }


    if( SendDlgItemMessage(hX,IDC_RBNone, BM_GETCHECK,0,0) )
    {
        dwEntryType=0;
    }
        
    lpdtmSysTime = new SYSTEMTIME;
    lpdtmExpire = new FILETIME;
    lpdtmLastModified = new FILETIME;

    GetLocalTime(lpdtmSysTime);
    SystemTimeToFileTime(lpdtmSysTime,lpdtmExpire);
    SystemTimeToFileTime(lpdtmSysTime,lpdtmLastModified);
    delete(lpdtmSysTime);

    lpszUrl = new TCHAR[MAX_PATH];
    lpszFileName = new TCHAR[MAX_PATH];
    lpszExt = new TCHAR[5];
    lpszSize = new TCHAR[10];

    GetDlgItemText(hX,IDC_SourceURL,lpszUrl,MAX_PATH);
    GetDlgItemText(hX,IDC_LocalFile,lpszFileName,MAX_PATH);
    GetDlgItemText(hX,IDC_FileExt,lpszExt,5);

    GetDlgItemText(hX,IDC_SizeLow,lpszSize,10);
    dwSize = (DWORD)_ttol(lpszSize);
    delete(lpszSize);

    if (dwSize==0)
    {
        if((MessageBox(hX,
                       TEXT("Incorrect File Size.\nUsing 8000 characters, Okay?\n"),
                       TEXT("Commit Entry"),MB_YESNO))
                        ==IDYES)
        {
            dwSize = 8000;
        }
        else
        {
            return FALSE;
        }
    }

    lpszData = new TCHAR[dwSize];
    GetDlgItemText(hX,IDC_CacheDump,lpszData,dwSize);
        
     err = _tfopen_s(&lpfCacheEntry,lpszFileName,_T("w"));
     if (err)
        return FALSE;
    fprintf(lpfCacheEntry,"%s",lpszData);
    fclose(lpfCacheEntry);
    delete(lpszData);

    if ( !CommitUrlCacheEntry( lpszUrl, 
                               lpszFileName, 
                               *lpdtmExpire,
                               *lpdtmLastModified, 
                               dwEntryType,
                               NULL,
                               0,
                               lpszExt,
                               0) )
    {
        ErrorOut(hX,GetLastError(),TEXT("Commit Cache Entry"));
        delete(lpszUrl);
        delete(lpszFileName);
        delete(lpszExt);
        delete(lpdtmExpire);
        delete(lpdtmLastModified);
        return FALSE;
    }
    else
    {
        delete(lpszUrl);
        delete(lpszFileName);
        delete(lpszExt);
        delete(lpdtmExpire);
        delete(lpdtmLastModified);
        return TRUE;
    }
}

キャッシュ エントリの削除

DeleteUrlCacheEntry 関数は URL を受け取り、それに関連付けられているキャッシュ ファイルを削除します。 キャッシュ ファイルが存在しない場合、関数は失敗し、 GetLastError は ERROR_FILE_NOT_FOUNDを返します。 キャッシュ ファイルが現在ロックされているか使用中の場合、関数は失敗し、 GetLastError は ERROR_ACCESS_DENIEDを返します。 ロックが解除されると、ファイルが削除されます。

キャッシュ エントリ ファイルの取得

リソースのファイル名を必要とするアプリケーションの場合は、 RetrieveUrlCacheEntryFile 関数と UnlockUrlCacheEntryFile 関数 使用します。 ファイル名を必要としないアプリケーションでは、RetrieveUrlCacheEntryStreamReadUrlCacheEntryStream、UnlockUrlCacheEntryStream 関数を使用して、キャッシュ内の情報を取得する必要があります。

RetrieveUrlCacheEntryStream は URL 解析を行わないので、リソースがキャッシュされている場合でも、アンカー (#) を含む URL はキャッシュに見つかりません。 たとえば、URL が "https://example.com/example.htm#sample"が渡された場合、関数は"https://example.com/example.htm" の場合でもERROR_FILE_NOT_FOUNDを返します。はキャッシュ内にあります。

RetrieveUrlCacheEntryFile は 、URL、 INTERNET_CACHE_ENTRY_INFO 構造体を格納するバッファー、およびバッファー サイズを受け入れます。 関数が取得され、呼び出し元に対してロックされます。

ファイル内の情報を使用した後、アプリケーションは UnlockUrlCacheEntryFile を呼び出してファイルのロックを解除する必要があります。

キャッシュ グループ

キャッシュ グループを作成するには、キャッシュ グループの GROUPID を生成するために CreateUrlCacheGroup 関数を呼び出す必要があります。 エントリは、キャッシュ エントリの URL と INTERNET_CACHE_GROUP_ADD フラグを SetUrlCacheEntryGroup 関数に指定することで、キャッシュ グループに追加できます。 グループからキャッシュ エントリを削除するには、キャッシュ エントリの URL とINTERNET_CACHE_GROUP_REMOVE フラグを SetUrlCacheEntryGroup に渡します。

FindFirstUrlCacheEntryEx 関数と FindNextUrlCacheEntryEx 関数を使用して、指定したキャッシュ グループ内のエントリを列挙できます。 列挙が完了すると、関数は FindCloseUrlCache を呼び出す必要があります。

可変サイズ情報を使用した構造体の処理

キャッシュには、格納されている各 URL の可変サイズ情報を含めることができます。 これは、 INTERNET_CACHE_ENTRY_INFO 構造体に反映されます。 キャッシュ関数がこの構造体を返すと、常に INTERNET_CACHE_ENTRY_INFO のサイズに可変サイズ情報を加えたバッファーが作成されます。 ポインター メンバーが NULL でない場合は、構造体の直後のメモリ領域を指します。 次の例に示すように、関数によって返されたバッファーを別のバッファーにコピーするときに、新しいバッファー内の適切な場所を指すようにポインター メンバーを固定する必要があります。

lpDstCEInfo->lpszSourceUrlName = 
    (LPINTERNET_CACHE_ENTRY_INFO) ((LPBYTE) lpSrcCEInfo + 
       ((DWORD)(lpOldCEInfo->lpszSourceUrlName) - (DWORD)lpOldCEInfo));

関数によって取得されたキャッシュ エントリ情報を格納するには小さすぎるバッファーを指定すると、一部のキャッシュ関数はERROR_INSUFFICIENT_BUFFERエラー メッセージで失敗します。 この場合、関数はバッファーの必要なサイズも返します。 その後、適切なサイズのバッファーを割り当てて、関数をもう一度呼び出すことができます。

注意

WinINet では、サーバーの実装はサポートされていません。 また、サービスから使用しないでください。 サーバーの実装またはサービスの場合は、 Microsoft Windows HTTP サービス (WinHTTP) を使用します。