我想实现的效果是:假如缓存中已经保存了网页中的图片的话,则就不用再次请求服务器端了,而是直接从缓存中获取,这样就提高了效率。可是页面不能直接读取缓存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
我调用了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
解决方案 »
- 对于MySQL能否使用强类型DataSet?
- DbDataAdapter.Update是更新哪里的数据?
- 找个高手帮忙把这个易语言代码转换成C#,或者自己写个C#也行,真的好难,转换半天也无能为力。
- object 转为 List的问题
- 请教 哪个枚举是图片的后缀名 ?
- 货币格式转换。
- 求助 ::windows应用程序里面可以把图片设置成按扭么
- datagrid中如何在一行中显示多条记录!
- 请问如何在C#中实现数据的批量存储,如下所示..........
- [共200分]关于数码图片噪点用C#做编辑的问题,欢迎大家讨论。
- C#导入一个带有固定表头excel表格,我怎样才能从表的第6行开始查询数据
- 请教这段代码在C#中如何写
自己来答呗!
我们无需判断要显示的图片是否保存在缓存中,因为浏览器自动判断了,自动优先读取缓存中的文件!我们只要在客户端计算出并设定每张图片的src是多少就可以了,这样也不用提交到服务器。
反正我要的效果就是不要提交到服务器端执行,全部都在客户端实现!