Кэширование (Windows Internet)

Функции WinINet имеют простую, но гибкую встроенную поддержку кэширования. Все данные, полученные из сети, кэшируются на жестком диске и извлекаются для последующих запросов. Приложение может управлять кэшированием для каждого запроса. Для HTTP-запросов с сервера большинство полученных заголовков также кэшируются. При выполнении HTTP-запроса из кэша кэша кэшированные заголовки также возвращаются вызывающей объекту. Это упрощает скачивание данных, независимо от того, поступают ли данные из кэша или из сети.

Приложения должны правильно выделить буфер, чтобы получить требуемые результаты при использовании функций постоянного кэширования URL-адресов. Дополнительные сведения см. в разделе Использование буферов.

Поведение кэша во время обработки ответа

Кэш WinINet соответствует директивам управления кэшем HTTP, описанным в RFC 2616. Директивы управления кэшем и флаги набора приложений определяют, что может быть кэшировано; Однако WinINet определяет, что на самом деле кэшируется, на основе следующего критерия:

  • WinINet кэширует только ответы HTTP и FTP.
  • Кэш может хранить только правильно выполненные ответы и использовать в ответе на последующий запрос. Ответы с надлежащим поведением определяются как ответы, которые возвращаются успешно.
  • По умолчанию WinINet кэширует успешные ответы, если только директива управления кэшем с сервера или определенный приложением флаг не указывают на то, что ответ может не кэшироваться.
  • Как правило, ответы на команду GET кэшируются, если выполняются перечисленные выше требования. Ответы на команды PUT и POST ни при каких обстоятельствах не кэшируются.
  • Элементы будут кэшироваться даже при заполнении кэша. Если добавленный элемент превышает предельный размер кэша, планируется очистка кэша. По умолчанию элементы не гарантированно будут храниться в кэше более 10 минут. Дополнительные сведения см. в разделе Кэш-мусорщик ниже.
  • По умолчанию https кэшируется. Это управляется глобальным параметром, который не может быть переопределен директивами кэша, определяемыми приложением. Чтобы переопределить глобальный параметр, выберите апплет Свойства браузера на панели управления и перейдите на вкладку Дополнительно. Установите флажок "Не сохранять зашифрованные страницы на диск" в разделе "Безопасность".

Кэш scavenger

Сборщик кэша периодически очищает элементы из кэша. Если элемент добавляется в кэш и кэш заполнен, он добавляется в кэш и планируется очистка кэша. Если сборщик кэша завершает цикл очистки и кэш не достиг предела кэша, то при добавлении другого элемента в кэш планируется еще один раунд. Как правило, очистка мусора планируется, когда добавленный элемент помещает кэш сверх предельного размера. По умолчанию минимальное время жизни в кэше равно 10 минутам, если иное не указано в директиве управления кэшем. При инициации очистки кэша нет никакой гарантии, что самые старые элементы будут удалены первыми из кэша.

Кэш является общим для всех приложений WinINet на компьютере для одного пользователя. Начиная с Windows Vista и Windows Server 2008, размер кэша устанавливается равным 1/32 размера диска с минимальным размером 8 МБ и максимальным размером 50 МБ.

Использование флагов для управления кэшированием

Флаги кэширования позволяют приложению контролировать, когда и как оно использует кэш. Эти флаги можно использовать отдельно или в сочетании с параметром 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_FORMS_SUBMIT INTERNET_FLAG_FROM_CACHE Не выполняет сетевые запросы. Все сущности возвращаются из кэша. Если запрошенного элемента нет в кэше, возвращается подходящая ошибка, например 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. Этот флаг можно использовать в HttpOpenRequest и InternetOpenUrl (только 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-адресов позволяют приложению получать доступ к информации, хранящейся в кэше, и управлять ими.

Функция Описание
CommitUrlCacheEntryA Кэширует данные в указанном файле в хранилище кэша и связывает их с заданным URL-адресом.
CommitUrlCacheEntryW Кэширует данные в указанном файле в хранилище кэша и связывает их с заданным URL-адресом.
CreateUrlCacheEntry Выделяет запрошенное хранилище кэша и создает локальное имя файла для сохранения записи кэша, соответствующей имени источника.
CreateUrlCacheGroup Создает идентификацию группы кэша.
DeleteUrlCacheEntry Удаляет файл, связанный с именем источника, из кэша, если файл существует.
DeleteUrlCacheGroup Освобождает GROUPID и любое связанное состояние в файле индекса кэша.
FindCloseUrlCache Закрывает указанный дескриптор перечисления.
FindFirstUrlCacheEntry Начинает перечисление кэша.
FindFirstUrlCacheEntryEx Начинает отфильтрованное перечисление кэша.
FindNextUrlCacheEntry Извлекает следующую запись в кэше.
FindNextUrlCacheEntryEx Извлекает следующую запись в перечислении отфильтрованного кэша.
GetUrlCacheEntryInfo Извлекает сведения о записи кэша.
GetUrlCacheEntryInfoEx Выполняет поиск URL-адреса после перевода всех кэшированных перенаправлений, которые будут применяться httpSendRequest в автономном режиме.
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. Для первоначального выделения буфера используется MAX_CACHE_ENTRY_INFO_SIZE, так как в ранних версиях API WinINet кэш не перечисляется должным образом. Более поздние версии правильно перечисляют кэш, и размер кэша не ограничен. Все приложения, которые выполняются на компьютерах с версией API WinINet из Интернета Обозреватель 4.0, должны выделять буфер требуемого размера. Дополнительные сведения см. в разделе Использование буферов.

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 позволяет получить структуру INTERNET_CACHE_ENTRY_INFO для указанного URL-адреса. Эта структура содержит размер структуры, 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" передается, функция возвращает ERROR_FILE_NOT_FOUND, даже если "https://example.com/example.htm" находится в кэше.

В следующем примере извлекаются сведения о записи кэша для указанного 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 в записи кэша. После записи данных в файл с помощью fopen, fprintf и 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 . Приложения, которым не требуется имя файла, должны использовать функции RetrieveUrlCacheEntryStream, ReadUrlCacheEntryStream и UnlockUrlCacheEntryStream для получения сведений в кэше.

RetrieveUrlCacheEntryStream не выполняет синтаксический анализ URL-адресов, поэтому URL-адрес, содержащий привязку (#), не будет найден в кэше, даже если ресурс кэширован. Например, если URL-адрес "https://example.com/example.htm#sample" передается, функция возвращает ERROR_FILE_NOT_FOUND, даже если "https://example.com/example.htm" находится в кэше.

RetrieveUrlCacheEntryFile принимает URL-адрес, буфер, в котором хранится структура INTERNET_CACHE_ENTRY_INFO , и размер буфера. Функция извлекается и блокируется для вызывающего.

После использования сведений в файле приложение должно вызвать UnlockUrlCacheEntryFile , чтобы разблокировать файл.

Группы кэша

Чтобы создать группу кэша, необходимо вызвать функцию CreateUrlCacheGroup , чтобы создать GROUPID для группы кэша. Записи можно добавить в группу кэша, указав 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).