我想实现的效果是:假如缓存中已经保存了网页中的图片的话,则就不用再次请求服务器端了,而是直接从缓存中获取,这样就提高了效率。可是页面不能直接读取缓存Temporary Internet Files文件夹中的文件。
我调用了wininet.dll接口,虽然可以判断图片是否已经在缓存中存在并获取到其的Internet地址,但是设置图片的ImageUrl=Internet地址的话,还是请求了服务器,有没有什么方法使缓存中的图片路径转变本地路径,从而使页面能够读取显示?
参考代码:    [DllImport("wininet.dll", SetLastError = true, CharSet = CharSet.Auto)]
    public static extern IntPtr FindFirstUrlCacheEntry([MarshalAs(UnmanagedType.LPTStr)] string lpszUrlSearchPattern,IntPtr lpFirstCacheEntryInfo,ref int lpdwFirstCacheEntryInfoBufferSize);
    
    [DllImport("wininet.dll", SetLastError = true, CharSet = CharSet.Auto)]
    public static extern bool FindNextUrlCacheEntry(IntPtr hEnumHandle,IntPtr lpNextCacheEntryInfo,ref int lpdwNextCacheEntryInfoBufferSize);    [DllImport("wininet.dll")]
    public static extern bool FindCloseUrlCache(IntPtr hEnumHandle);    [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    public static extern int FileTimeToSystemTime(IntPtr lpFileTime,IntPtr lpSystemTime);    #region 引入dll
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    public struct INTERNET_CACHE_ENTRY_INFO
    {
        public int dwStructSize;
        public IntPtr lpszSourceUrlName;
        public IntPtr lpszLocalFileName;
        public int CacheEntryType;
        public int dwUseCount;
        public int dwHitRate;
        public int dwSizeLow;
        public int dwSizeHigh;
        public System.Runtime.InteropServices.ComTypes.FILETIME LastModifiedTime;
        public System.Runtime.InteropServices.ComTypes.FILETIME ExpireTime;
        public System.Runtime.InteropServices.ComTypes.FILETIME LastAccessTime;
        public System.Runtime.InteropServices.ComTypes.FILETIME LastSyncTime;
        public IntPtr lpHeaderInfo;
        public int dwHeaderInfoSize;
        public IntPtr lpszFileExtension;
        public int dwExemptDelta;
    }    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    public struct SYSTEMTIME
    {
        public short wYear;
        public short wMonth;
        public short wDayOfWeek;
        public short wDay;
        public short wHour;
        public short wMinute;
        public short wSecond;
        public short wMilliseconds;
    }    const int ERROR_NO_MORE_ITEMS = 259;
    #endregion
    #region FileTimeToSystemTime    private string FILETIMEtoDataTime(System.Runtime.InteropServices.ComTypes.FILETIME time)
    {
        IntPtr filetime = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(System.Runtime.InteropServices.ComTypes.FILETIME)));
        IntPtr systime = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SYSTEMTIME)));
        Marshal.StructureToPtr(time, filetime, true);
        FileTimeToSystemTime(filetime, systime);
        SYSTEMTIME st = (SYSTEMTIME)Marshal.PtrToStructure(systime, typeof(SYSTEMTIME));
        string Time = st.wYear.ToString() + "." + st.wMonth.ToString() + "." + st.wDay.ToString() + "." + st.wHour.ToString() + "." + st.wMinute.ToString() + "." + st.wSecond.ToString();
        return Time;
    }
    #endregion    #region 加载数据
    private void FileOk_Click(object sender, System.EventArgs e)
    {
        int nNeeded = 0, nBufSize;
        IntPtr buf;
        INTERNET_CACHE_ENTRY_INFO CacheItem;
        IntPtr hEnum;
        bool r;
        FindFirstUrlCacheEntry(null, IntPtr.Zero, ref nNeeded);
        if (Marshal.GetLastWin32Error() == ERROR_NO_MORE_ITEMS)
            return;
        nBufSize = nNeeded;
        buf = Marshal.AllocHGlobal(nBufSize);
        hEnum = FindFirstUrlCacheEntry(null, buf, ref nNeeded);        string[] TEST = new string[10000];
        int step = 0;
        while (true)
        {
            CacheItem = (INTERNET_CACHE_ENTRY_INFO)Marshal.PtrToStructure(buf,
            typeof(INTERNET_CACHE_ENTRY_INFO));
            string modifiedTime = FILETIMEtoDataTime(CacheItem.LastModifiedTime);
            string expireTime = FILETIMEtoDataTime(CacheItem.ExpireTime);
            string accessTime = FILETIMEtoDataTime(CacheItem.LastAccessTime);
            string syncTime = FILETIMEtoDataTime(CacheItem.LastSyncTime);
            #region 获得数据,存入数据库
            try
            {
                //此处遍历CacheItem即可
                //例如
                string B = Marshal.PtrToStringAuto(CacheItem.lpszSourceUrlName);                
            }
            catch
            {
                //异常处理
            }
            #endregion
            string s = Marshal.PtrToStringAuto(CacheItem.lpszSourceUrlName);            nNeeded = nBufSize;
            r = FindNextUrlCacheEntry(hEnum, buf, ref nNeeded);            if (!r && Marshal.GetLastWin32Error() == ERROR_NO_MORE_ITEMS)
                break;
            if (!r && nNeeded > nBufSize)
            {
                nBufSize = nNeeded;
                buf = Marshal.ReAllocHGlobal(buf, (IntPtr)nBufSize);
                FindNextUrlCacheEntry(hEnum, buf, ref nNeeded);
            }
        }
        Marshal.FreeHGlobal(buf);
    }
    #endregion

解决方案 »

  1.   

    像Google地图,他们也是读取缓存中的图片,才使已经预览过的页面,显示速度很快!但是不知他们是如何实现的~
      

  2.   

    没人回答!呵呵~
    自己来答呗!
    我们无需判断要显示的图片是否保存在缓存中,因为浏览器自动判断了,自动优先读取缓存中的文件!我们只要在客户端计算出并设定每张图片的src是多少就可以了,这样也不用提交到服务器。
    反正我要的效果就是不要提交到服务器端执行,全部都在客户端实现!