VC++ IE缓存管理研究
引言
关于IE缓存管理方面的资料非常少,网上虽然有部分文章介绍,也有工具下载(如搜索缓存或清除缓存等),但都不够全面和深入。
另外,IE缓存管理主要依赖几个index.dat文件和wininet库,而MSDN对wininet库的帮助非常简单,而且没有示例代码。
网上能够找到的资料大部分都是对wininet的http协议处理接口方面的介绍,对于缓存处理部分介绍的很少,加上这部分接口定义得有点晦涩,所以让人觉得有点困绕。
本文结合自己的项目经验,对IE的缓存机制,特别是wininet库中缓存管理的接口使用,提出全面深入的说明。
弄懂了wininet缓存管理接口,以后写缓存监控、缓存搜索和缓存清理等工具就非常简单了。
2. 术语定义
3. IE缓存文件
3.1. IE缓存分类
IE缓存主要分为3大类:cookie、临时文件(包括未过期的资源和脱机文件)、历史记录。
这3类缓存分别都有一个索引文件,文件名为index.dat。
缓存cookie索引:C:/Documents and Settings/liyafeng/Cookies/index.dat
历史记录索引:C:/Documents and Settings/liyafeng/Local Settings/History/History.IE5/index.dat。
这3个index.dat文件格式被加密处理过,微软没有公开也不打算公开文件格式,这种做法被很多人指责,但是微软依然我行我素。
通过IE的internet选项清除缓存时不能删除index.dat文件,但是在磁盘清除临时文件时会删除这3个index.dat文件。
目前访问这些索引文件的唯一方法是通过wininet库的相关接口,这也是本文重点介绍的地方。
注意:缓存的临时文件被文件系统做了特殊处理,只能通过完整目录路径访问,否则无法看到,即使你显示所有文件和系统文件。
3.2. IE缓存管理的流程
3、 如果不存在就创建cookie索引:C:/Documents and Settings/liyafeng/Cookies/index.dat。
4、 如果不存在历史记录就创建历史索引:C:/Documents and Settings/liyafeng/Local Settings/History/History.IE5/index.dat。
6、 设置回调函数,通过InternetSetStatusCallback。
12、 如果被缓存,则从缓存中读取相应的信息,包括最后修改时间、最后访问时间和过期时间。
14、 http服务器会检查访问的资源是否过期,如果未过期,则会返回“304 Not Modified”。
16、 如果第11步中没有被缓存,则直接从http服务器下载资源。
4. Wininet库的缓存管理接口
4.1. 简介
接口分为枚举缓存、创建缓存、查询缓存和删除缓存,以及对缓存组的操作。
4.2. 枚举缓存
FindFirstUrlCacheEntry 开始对缓存的枚举
FindFirstUrlCacheEntryEx 开始对缓存的过滤型枚举
FindNextUrlCacheEntry 返回缓存中的下一个条目
FindNextUrlCacheEntryEx 在过滤型枚举中返回下一个缓存条目
FindFirstUrlCacheEntry函数要求传入搜索模式和用于存储INTERNET_CACHE_ENTRY_INFO结构体的缓冲区及其尺寸。当前仅实现了默认搜索模式,它返回所有缓存条目。
缓存枚举完成后,应该用FindCloseUrlCache关闭缓存枚举句柄。
注意:FindNextUrlCacheEntry返回FALSE时,有两种可能。一种是INTERNET_CACHE_ENTRY_INFO条目分配的缓冲区不够,另一种可能是枚举结束。
关于缓存区不够如何处理,还有嵌入式指针问题,在后面查询缓存中会给出示例代码。
4.3. 查询缓存条目信息
GetUrlCacheEntryInfo 获取某缓存条目的信息
GetUrlCacheEntryInfoEx 转换任何会被HttpSendRequest应用于离线模式的缓存重定向,然后搜索指定的URL。
typedef struct _INTERNET_CACHE_ENTRY_INFOA {
DWORD dwStructSize; // version of cache system.
LPSTR lpszSourceUrlName; // embedded pointer to the URL name string.
LPSTR lpszLocalFileName; // embedded pointer to the local file name.
DWORD CacheEntryType; // cache type bit mask.
DWORD dwUseCount; // current users count of the cache entry.
DWORD dwHitRate; // num of times the cache entry was retrieved.
DWORD dwSizeLow; // low DWORD of the file size.
DWORD dwSizeHigh; // high DWORD of the file size.
FILETIME LastModifiedTime; // last modified time of the file in GMT format.
FILETIME ExpireTime; // expire time of the file in GMT format
FILETIME LastAccessTime; // last accessed time in GMT format
FILETIME LastSyncTime; // last time the URL was synchronized
LPSTR lpHeaderInfo; // embedded pointer to the header info.
DWORD dwHeaderInfoSize; // size of the above header.
LPSTR lpszFileExtension; // File extension used to retrive the urldata as a file.
union { // Exemption delta from last access time.
}; // Exemption delta from last access
} INTERNET_CACHE_ENTRY_INFOA, * LPINTERNET_CACHE_ENTRY_INFOA;
注意:embedded pointer即嵌入式指针,是一个比较晦涩的点,真实意义是在结构体后分配一块连续内存,然后让这个指针指向它,就好象是嵌入在结构体内,因此得名。
INTERNET_CACHE_ENTRY_INFOA *lpCacheEntryInfo = new INTERNET_CACHE_ENTRY_INFOA;
DWORD cbCacheEntryInfo = sizeof(INTERNET_CACHE_ENTRY_INFOA);
BOOL fOk = GetUrlCacheEntryInfoA(lpszUrl,lpCacheEntryInfo,&cbCacheEntryInfo);
if( !fOk && cbCacheEntryInfo > sizeof(INTERNET_CACHE_ENTRY_INFOA) )
lpCacheEntryInfo = (LPINTERNET_CACHE_ENTRY_INFOA) new char[cbCacheEntryInfo];//强制转换,保证指针可以指向结构体内部。
fOk = GetUrlCacheEntryInfoA(lpszUrl,lpCacheEntryInfo,&cbCacheEntryInfo);
PR_DEBUG("do again:fOk:%d,cbCacheEntryInfo:%d",fOk,cbCacheEntryInfo);
4.4. 创建缓存条目
CreateUrlCacheEntry 分配请求的缓存存储器,创建本地文件名用于保存对应源名称的缓存条目
CommitUrlCacheEntry 缓存存储器中某特定文件中的数据,将它与给定的URL关联起来
使用CreateUrlCacheEntry和CommitUrlCacheEntry可以创建缓存条目。
CommitUrlCacheEntry接受URL、本地文件名、失效时间、最后修改时间、缓存条目类型、头部信息及其尺寸和文件扩展名,在缓存存储器中保存文件数据,并与给定的URL关联起来。
4.5. 删除缓存条目
DeleteUrlCacheEntry 如果缓存中存在与源名称相关的文件,删除它。
4.6. 获取缓存文件
RetrieveUrlCacheEntryFile 以文件的形式从缓存中获取一个缓存条目
UnlockUrlCacheEntryFile 解锁因为使用RetrieveUrlCacheEntryFile从缓存中获取其文件用于使用而被锁定的缓存条目。
对于要求某资源的文件名才能的启动的应用程序,可使用RetrieveUrlCacheEntryFile和UnlockUrlCacheEntryFile函数。
不要求文件名的程序应该使用RetrieveUrlCacheEntryStream、ReadUrlCacheEntryStream和UnlockUrlCacheEntryStream获取缓存信息。
RetrieveUrlCacheEntryFile接受一个URL和用于保存INTERNET_CACHE_ENTRY_INFO结构体的缓冲区及其尺寸,为调用者获取并锁定缓存文件。
使用完缓存文件后,应该调用UnlockUrlCacheEntryFile解锁文件。
注意:虽然你也可以直接使用readfile来读取缓存条目,但是此时对文件没有加锁,因此在读取的过程中可能会被修改或删除,因此推荐使用RetrieveUrlCacheEntryFile。
4.7. 获取缓存流
RetrieveUrlCacheEntryStream 提供最高效的、实现无关的访问缓存数据的方法。
ReadUrlCacheEntryStream 从RetrieveUrlCacheEntryStream打开的流中读取缓存数据。
RetrieveUrlCacheEntryStream、ReadUrlCacheEntryStream和UnlockUrlCacheEntryStream用于获取缓存中的资源。
获取缓存文件后,应该调用UnlockUrlCacheEntryStream关闭RetrieveUrlCacheEntryStream创建的句柄。
注意:流操作主要针对不关心本地文件名的应用,所有读取和关闭流的操作都必须使用RetrieveUrlCacheEntryStream返回的句柄。
4.8. 缓存组操作
SetUrlCacheEntryGroup 向缓存组添加条目,或者从中删除条目
DeleteUrlCacheGroup 释放GROUPID以及缓存索引文件中任何与之相关的状态
FindFirstUrlCacheEntryEx和FindNextUrlCacheEntryEx函数可以枚举指定缓存组中的条目。完成枚举后,应该用FindCloseUrlCache关闭枚举句柄。
VC++ IE缓存管理研究相关推荐
- flutter图片识别_Flutter 图片解码与缓存管理研究
写作费时,敬请点赞,关注,收藏三连. 图片解码和缓存管理是渲染引擎的一个重要模块,这是因为图片解码的耗时很长,特别是对于设计为跨平台的通用渲染引擎来说,依赖于CPU来做图片解码,会消耗大量的CPU时间 ...
- HDFS集中式缓存管理(Centralized Cache Management)
Hadoop从2.3.0版本号開始支持HDFS缓存机制,HDFS同意用户将一部分文件夹或文件缓存在HDFS其中.NameNode会通知拥有相应块的DataNodes将其缓存在DataNode的内存其中 ...
- 基于吉日嘎拉的通用权限管理WebForm版扩展:字典选项管理和缓存管理
关于字典管理,其实就是2个表,一个表记录字典和对应表,另一个表记录字典内容.我这里改名为字典选项,其实是一个意思.直接上图: 这里的字典选项是分子系统的,每个子系统可以有自己的单独字典,方便管理.但是 ...
- Webview离线功能(优先cache缓存+cache缓存管理)
在做Webview显示服务器的html功能时 需要加入离线功能. 开始思路很狭隘,以为一定应该是从服务器得到的html文件,下载到本地后加载~ 但是这样不能离线查看图片,因为图片数据并不再html中, ...
- HDFS集中式的缓存管理原理与代码剖析--转载
原文地址:http://yanbohappy.sinaapp.com/?p=468 Hadoop 2.3.0已经发布了,其中最大的亮点就是集中式的缓存管理(HDFS centralized cache ...
- Spring Cache抽象-缓存管理器
概述 SimpleCacheManager NoOpCacheManager ConcurrentMapCacheManager CompositeCacheManager 概述 CacheManag ...
- 数据库的缓存管理[ASPNET2.0深入挖掘系列听后感]
工作时间也不短了,说实话感觉是越来越郁闷:以前经常为实现某项功能而高兴半天,现在这种感觉仿佛离我越来越远:整天工作大部分就是Copy,Edit,一点创意都没有,而且那些代码我自己看起来都感觉很垃圾.不 ...
- Androi App缓存管理
转自:http://www.cnblogs.com/qianxudetianxia/archive/2012/02/20/2112128.html 无论大型或小型应用,灵活的缓存可以说不仅大大减轻了服 ...
- Android之图片缓存管理
如果每次加载同一张图片都要从网络获取,那代价实在太大了.所以同一张图片只要从网络获取一次就够了,然后在本地缓存起来,之后加载同一张图片时就从缓存中加载就可以了.从内存缓存读取图片是最快的,但是因为内存 ...
- spring默认缓存管理器_使用Spring的缓存管理器缓存Web内容
spring默认缓存管理器 在这篇文章中,我想向大家展示如何使用Spring的CacheManager,@ Cacheable和JMX批注来缓存和管理Web内容的缓存的基础知识. 想象一下一个网上商店 ...
最新文章
- springCloud全家桶
- 干货 | 斯坦福的人工智能4年路线!
- Hadoop教程(五):Flume、Sqoop、Pig、Hive、OOZIE
- C++ 读入优化与输出优化 模板
- python多进程参考代码
- 2014年4月java程序设计,2014年4月 Java语言程序设计(一)试题答案.doc
- Hadoop: The Definitive Guide (3rd Edition)
- Java多线程学习十二: synchronized的工作原理 以及背后的“monitor 锁”
- qdialog 只有点击才能获得焦点_使用金属激光切割机时该注意什么才能保证产品质量?...
- linux 下sqlplus里无法使用方向键的解决
- 聊一聊Cookie(结合自己的学习方法分享一篇维基百科和一篇segmentfault(思否)好文)...
- html图表实现,用 Flotr2 实现的 HTML5 图表
- 最小二乘法计算平面度
- 电脑上怎么把mov转换成mp4?
- DOS命令diskpart格式化磁盘
- 也来说是 AngularJS、 Angular 2、Angular 4 的区别
- 什么叫MD5,MD5通常做什么用处,为什么MD5不可逆,用做密码加密的时候仍然可能会被解密?
- OpenCV快速入门一:图片读取保存
- Redis哨兵模式实现主从切换
- 国庆七天测(五)马里奥