C++实现IE缓存迭代器
来源:互联网 发布:四川旅游五天 知乎 编辑:程序博客网 时间:2024/05/17 09:03
1、迭代器的定义:
提供一种方法,使之能够依序访问某个聚合物(容器)所含的各个元素,而又无需暴露该聚合物的内部表述方式。
2、迭代器的设计动机
一个聚合对象,应该提供一种方法来让别人可以访问它的元素,而又不需暴露它的内部结构。此外,针对不同的需要,可能要以不同的方式遍历这个容器。但即使可以预见到所需的那些遍历操作,你可能也不希望容器的接口中充斥着各种不同的遍历的操作。有时可能需要在同一个容器上同时进行多个遍历。
迭代器模式的关键思想是将对列表的访问和遍历从容器对象中分离出来并放入一个迭代器(iterator)对象中。迭代器类定义了一个访问该容器的接口。迭代器对象负责跟踪当前的元素;即它知道哪些元素已经遍历过了。将遍历机制与列表对象分离使我们可以定义不同的迭代器来实现不同的遍历策略,而无需在容器接口中列举它们。
一般一个迭代器类需要提供以下操作:
(1) First():初始化迭代器,使当前元素指向列表的第一个元素。
(2) Next():将当前元素指针向前推进一步,指向下一个元素。
(3) CurrentItem():返回容器中的当前元素。
(4) IsDone():检查是否已越过最后一个元素,也就是完成了本次遍历。
3、迭代器的适用性
(1)访问一个聚合对象的内容而无需暴露它的内部表示。
(2)支持对聚合对象的多种遍历
(3)为遍历不同的聚合结构提供一个统一的接口
4、空迭代器
一个空迭代器(NullIterator)是一个退化的迭代器,它有助于处理边界条件,根据定义,空迭代器总是已经完成了遍历,即,它的IsDone操作总是返回true;
5、例子——IE缓存迭代器
以下用C++实现一个迭代器类,用于遍历IE缓存空间。我们在访问网站或本地文件时,系统会把图片、动画、浏览记录等信息保存在Internet临时文件夹中,但这个文件夹是一个隐藏文件夹,不同于普通文件夹,Win32 API给用户提供了很多接口用于访问,修改这个文件夹里的内容。为了展示怎样怎样设计IE缓存迭代器,需要用到以下Win32 API。
5.1 需要用到的Win32 API
最低配置,头文件、库及动态链接库:
Minimum supported client
Windows 2000 Professional [desktop apps only]
Minimum supported server
Windows 2000 Server [desktop apps only]
Header
Wininet.h
Library
Wininet.lib
DLL
Wininet.dll
(1)IE缓存的入口点
HANDLE FindFirstUrlCacheEntry( _In_ LPCTSTR lpszUrlSearchPattern, _Out_ LPINTERNET_CACHE_ENTRY_INFO lpFirstCacheEntryInfo, _Inout_ LPDWORD lpcbCacheEntryInfo);
参数:
lpszUrlSearchPattern [in]:一个字符串指针,该字符串指定索引模式,该参数只能被设定为以下三个值:
“cookie:”:列举出IE缓存的cookie;
“visited:”:列表出缓存空间中的URL历史记录;
NULL:列表出缓存空间中的所有内容
lpFirstCacheEntryInfo [out]:指向 INTERNET_CACHE_ENTRY_INFO 结构的指针
lpcbCacheEntryInfo [in,out]:指向DWORD变量的指针,用于指定lpcbCacheEntryInfo缓冲区的大小,以字节为单位。当函数返回时,该变量包含了该缓冲区的实际大小。
返回值:
返回一个被FindNextUrlCacheEntry访问随后的缓存空间所使用的句柄,如果该函数失败,则返回NULL。要想得到扩展错误信息,调用GetLastError函数获取。
(2) 获取IE缓存的下一个入口点
BOOL FindNextUrlCacheEntry( _In_ HANDLE hEnumHandle, _Out_ LPINTERNET_CACHE_ENTRY_INFO lpNextCacheEntryInfo, _Inout_ LPDWORD lpcbCacheEntryInfo);
参数:
hEnumHandle [in]:调用FindFirstUrlCacheEntry返回的句柄
lpNextCacheEntryInfo [out]:指向INTERNET_CACHE_ENTRY_INFO 结构的指针
lpcbCacheEntryInfo [in,out]:指向DWORD变量的指针,用于指定lpcbCacheEntryInfo缓冲区的大小,以字节为单位。当函数返回时,该变量包含了该缓冲区的实际大小。
返回值:
如果成功则返回true,否则返回false.要想获取扩展错误信息,需要调用GetLastError,可能的错误值如下:
ERROR_INSUFFICIENT_BUFFER:lpcbCacheEntryInfo不足以提供lpNextCacheEntryInfo 指定的大小,函数返回时,lpcbCacheEntryInfo包含lpcbCacheEntryInfo指定的实际大小。
ERROR_NO_MORE_ITEMS:列举完成。
(3)关闭IE缓存句柄
BOOL FindCloseUrlCache( _In_ HANDLE hEnumHandle);
参数:
hEnumHandle [in]:调用FindFirstUrlCacheEntry返回的句柄
返回值:
如果成功则返回true,否则返回false.要想获取扩展错误信息,需要调用GetLastError。
(4)IE缓存结构体,包含IE缓存的信息
typedefstruct_INTERNET_CACHE_ENTRY_INFO { DWORD dwStructSize; LPTSTR lpszSourceUrlName; LPTSTR lpszLocalFileName; DWORD CacheEntryType; DWORD dwUseCount; DWORD dwHitRate; DWORD dwSizeLow; DWORD dwSizeHigh; FILETIME LastModifiedTime; FILETIME ExpireTime; FILETIME LastAccessTime; FILETIME LastSyncTime; LPTSTR lpHeaderInfo; DWORD dwHeaderInfoSize; LPTSTR lpszFileExtension; union { DWORD dwReserved; DWORD dwExemptDelta; };}INTERNET_CACHE_ENTRY_INFO,*LPINTERNET_CACHE_ENTRY_INFO;
由于该结构体成员比较多,在此不一一解译,请参考MSDNhttp://msdn.microsoft.com/zh-cn/library/windows/desktop/aa385134(v=vs.85).aspx
5.2、CacheIterator类
(1)成员变量
用以上三个API中可以得知,FindFirstUrlCacheEntry返回的句柄hEnumHandle,指向INTERNET_CACHE_ENTRY_INFO 结构的指针lpCacheEntryInfo,还有INTERNET_CACHE_ENTRY_INFO 的实际大小都是要经常用到的变量,因此把它们作为CacheIterator的成员变量,如下:
HANDLE m_hCacheEntry;
LPINTERNET_CACHE_ENTRY_INFO m_lpCacheEntryInfo;
DWORD m_dwNeedBufSize;
(2)成员函数
从迭代器模式需要提供的四个操作来看,First和Next操作和FindFirstUrlCacheEntry与FindNextUrlCacheEntry是一一对应的;CurrentItem用于返回m_lpCacheEntryInfo所指向的IE缓存结构体INTERNET_CACHE_ENTRY_INFO;为了处理边界条件,同样需要IsDone操作,该操作只需判断m_lpCacheEntryInfo是否为NULL.
为了给出具体的代码,在此选择C++语言进行描述。从面向对象来看,我们可以在构造函数中进行初始化,即实现First操作;由于C++语言具有操作符重载机制,我们可以在前置operator++(),和后置operator++(int)中实现Next操作;同样由于操作符重载,我们可以在operator*()中实现CurrentItem操作,该成员函数用于返回m_lpCacheEntryInfo指向INTERNET_CACHE_ENTRY_INFO结构体的一个引用;最后一个问题是怎样实现IsDone操作呢?即该操作用于处理边界条件,判断遍历是否结束。在此,如果我们在构造的时候能够构造一个空迭代器,即当迭代器为空的时候,表示IsDone,遍历完成。空迭代器很简单,我们只需要将其m_lpCacheEntryInfo设为NULL即可。由于我们要进行比较操作,所以需要重载operator==和operator!=操作符。如下,得到了以下成员函数:
explicit CacheIterator();
explicit CacheIterator(LPCSTR accessMethod);
booloperator==(constCacheIterator& rhs);
booloperator!=(constCacheIterator& rhs);
INTERNET_CACHE_ENTRY_INFO& operator*();
CacheIterator& operator++();
CacheIterator operator++(int );
(3)主要成员函数的实现
构造函数:
从FindFirstUrlCacheEntry的第一个参数lpszUrlSearchPattern,我们也需要提供两样的接口给用户指定访问模式。在无参构造函数中,我们指定lpszUrlSearchPattern为0,即可以访问IE缓存的全部内容。在CacheIterator(LPCSTRaccessMethod)中可以给accessMethod指定访问模式,当accessMethod为空时,我们设定为空迭代器。构造函数如下:
CacheIterator::CacheIterator(){ Init(0);} CacheIterator::CacheIterator(LPCSTR accessMethod) :m_hCacheEntry(0),m_lpCacheEntryInfo(0), m_dwNeedBufSize(0){ if(accessMethod != 0) Init(accessMethod);} void CacheIterator::Init(LPCSTR accessMethod){ FindFirstUrlCacheEntry(accessMethod,0, &m_dwNeedBufSize); m_lpCacheEntryInfo = reinterpret_cast<LPINTERNET_CACHE_ENTRY_INFO> (new char[m_dwNeedBufSize]); m_hCacheEntry = FindFirstUrlCacheEntry(accessMethod, m_lpCacheEntryInfo,&m_dwNeedBufSize);}
前置Operator++
CacheIterator& CacheIterator::operator++(){ if(!FindNextUrlCacheEntry(m_hCacheEntry, m_lpCacheEntryInfo,&m_dwNeedBufSize)) { delete[] m_lpCacheEntryInfo; switch(GetLastError()) { case ERROR_NO_MORE_ITEMS: FindCloseUrlCache(m_hCacheEntry); m_hCacheEntry= 0; break; case ERROR_INSUFFICIENT_BUFFER: m_lpCacheEntryInfo = reinterpret_cast<LPINTERNET_CACHE_ENTRY_INFO> (new char[m_dwNeedBufSize]); if(!FindNextUrlCacheEntry(m_hCacheEntry, m_lpCacheEntryInfo, &m_dwNeedBufSize)) { delete[] m_lpCacheEntryInfo; FindCloseUrlCache(m_hCacheEntry); m_lpCacheEntryInfo = 0; } break; default: FindCloseUrlCache(m_hCacheEntry); m_lpCacheEntryInfo = 0; break; } } return *this;}
6、完整代码:
///cacheiterator.h#ifndef__CACHEITERATOR_H__#define__CACHEITERATOR_H__ #include"windows.h"#include"wininet.h"#pragmacomment(lib,"wininet.lib") class CacheIterator{public: explicit CacheIterator(); explicit CacheIterator(LPCSTRaccessMethod); bool operator==(constCacheIterator& rhs); bool operator!=(constCacheIterator& rhs); INTERNET_CACHE_ENTRY_INFO& operator*(); CacheIterator& operator++(); CacheIterator operator++(int );private: void Init(LPCSTR accessMethod);private: HANDLE m_hCacheEntry; LPINTERNET_CACHE_ENTRY_INFO m_lpCacheEntryInfo; DWORD m_dwNeedBufSize;};#endif ///cacheiterator.cpp#include"cacheiterator.h" CacheIterator::CacheIterator(){ Init(0);} CacheIterator::CacheIterator(LPCSTR accessMethod) :m_hCacheEntry(0),m_lpCacheEntryInfo(0),m_dwNeedBufSize(0){ if(accessMethod != 0) Init(accessMethod);} void CacheIterator::Init(LPCSTR accessMethod){ FindFirstUrlCacheEntry(accessMethod,0,&m_dwNeedBufSize); m_lpCacheEntryInfo = reinterpret_cast<LPINTERNET_CACHE_ENTRY_INFO> (new char[m_dwNeedBufSize]); m_hCacheEntry = FindFirstUrlCacheEntry(accessMethod, m_lpCacheEntryInfo,&m_dwNeedBufSize);} bool CacheIterator::operator==(const CacheIterator& rhs){ return m_hCacheEntry == rhs.m_hCacheEntry;} bool CacheIterator::operator!=(const CacheIterator& rhs){ return !(*this == rhs);} INTERNET_CACHE_ENTRY_INFO& CacheIterator::operator*(){ return *m_lpCacheEntryInfo;} CacheIterator& CacheIterator::operator++(){ if(!FindNextUrlCacheEntry(m_hCacheEntry,m_lpCacheEntryInfo,&m_dwNeedBufSize)) { delete[] m_lpCacheEntryInfo; switch(GetLastError()) { case ERROR_NO_MORE_ITEMS: FindCloseUrlCache(m_hCacheEntry); m_hCacheEntry = 0; break; case ERROR_INSUFFICIENT_BUFFER: m_lpCacheEntryInfo = reinterpret_cast<LPINTERNET_CACHE_ENTRY_INFO> (new char[m_dwNeedBufSize]); if(!FindNextUrlCacheEntry(m_hCacheEntry,m_lpCacheEntryInfo, &m_dwNeedBufSize)) { delete[] m_lpCacheEntryInfo; FindCloseUrlCache(m_hCacheEntry); m_lpCacheEntryInfo = 0; } break; default: FindCloseUrlCache(m_hCacheEntry); m_lpCacheEntryInfo = 0; break; } } return *this;} CacheIterator CacheIterator::operator++(int){ CacheIterator preCacheIter = *this; ++*this; return preCacheIter;}
7、测试——统计IE缓存的cookie项总数
int main(){ CacheIterator beg("cookie:"),end(0); int cnt = 0; for ( ; beg != end; ++beg) { //cout<<(*beg).lpszLocalFileName<<endl; ++cnt; } cout<<"sum of cookies ="<<cnt<<endl; return 0;}
8、更多参考资料
[1] http://msdn.microsoft.com/en-us/magazine/cc301955.aspx
[2] http://www.cnblogs.com/yelaiju/archive/2010/10/01/1839860.html
[3]Erich Gamma,Richard Helm等著.设计模式[M],北京:机械工业出版社,2012.6
[4]侯捷著.STL源码剖析[M],湖北:华中科技大学出版社,2011.12
注:欢迎各个网友指出错误,一起探讨,大家共同进步!
- C++实现IE缓存迭代器
- C#IE图片缓存不显示
- selenium启动ie配置,实现inprivate浏览,禁止ie缓存
- IE缓存
- IE缓存
- IE,缓存???
- IE缓存
- ie缓存
- ASP.NET(C#)中使IE缓存失效的代码
- 关于IE缓存的解决方案(HTML,JSP,ASP,PHP,C#)
- 关于IE缓存的解决方案(HTML,JSP,ASP,PHP,C#)
- C语言实现LRU缓存
- QTP加载第三方DLL实现清除IE缓存
- IE缓存函数
- IE缓存函数(PHP)
- VB清除IE缓存
- ie缓存问题
- IE浏览器的缓存
- 希望有懂经济的共同完成开源项目
- TestJDBC(22)
- 十六周上机任务(指来指去)
- 罗永浩 我的奋斗 摘抄
- codefores 4C(统计出现过的次数)
- C++实现IE缓存迭代器
- 从字符设备驱动浅析linux内核设计与实现
- 《那些年啊,那些事——一个程序员的奋斗史》——126
- Java模拟Post 提交表单数据
- 入门经典 第七章 7.2.1 生成1到N的排列
- 全局变量与头文件
- spring3.1.0 jar包详解说明
- 杭电Hd 2111
- 动态联编 和 静态联编