/// <summary> /// 新增缓存数据 /// </summary> public void Put(string key, Entry entry) { lock (this) { PruneIfNeeded(entry.Data.Length); var file = GetFileForKey(key); try { var fos = file.Open(FileMode.OpenOrCreate); CacheHeader e = new CacheHeader(key, entry); bool success = e.WriteHeader(fos); if (!success) { fos.Close(); VolleyLog.D("Failed to write header for {0}", file.FullName); throw new IOException(); } fos.Write(entry.Data, 0, entry.Data.Length); fos.Close(); PutEntry(key, e); return; } catch (IOException) { } file.Delete(); if (File.Exists(file.FullName)) { VolleyLog.D("Could not clean up file {0}", file.FullName); } } }
private void RemoveEntry(String key) { CacheHeader entry = null; mEntries.TryGetValue(key, out entry); if (entry != null) { mTotalSize -= entry.Size; mEntries.Remove(key); } }
/// <summary> /// 初始化缓存 /// </summary> public void Initialize() { lock (this) { if (!mRootDirectory.Exists) { mRootDirectory.Create(); if (!mRootDirectory.Exists) { VolleyLog.E("Unable to create cache dir {0}", mRootDirectory.FullName); } return; } //获取已缓存文件并添加到缓存表中 FileInfo[] files = mRootDirectory.GetFiles(); if (files == null) { return; } foreach (FileInfo file in files) { FileStream fs = null; try { fs = file.Open(FileMode.OpenOrCreate); CacheHeader entry = CacheHeader.ReadHeader(fs); entry.Size = fs.Length; PutEntry(entry.Key, entry); } catch (IOException) { if (file != null) { file.Delete(); } } finally { try { if (fs != null) { fs.Close(); } } catch (IOException) { } } } } }
/// <summary> /// 当需要的空间大于指定空间后清除部分缓存 /// </summary> private void PruneIfNeeded(int neededSpace) { if (mTotalSize + neededSpace < mMaxCacheSizeInBytes) { return; } if (VolleyLog.DEBUG) { VolleyLog.V("Pruning old cache entries."); } long before = mTotalSize; int prunedFiles = 0; long startTime = SystemClock.ElapsedRealtime(); Dictionary <string, CacheHeader> delDic = new Dictionary <string, CacheHeader>(); foreach (KeyValuePair <String, CacheHeader> pair in mEntries) { CacheHeader e = pair.Value; var fi = GetFileForKey(e.Key); fi.Delete(); if (!File.Exists(fi.FullName)) { mTotalSize -= e.Size; } else { VolleyLog.D("Could not delete cache entry for key={0},filename={1}", e.Key, GetFilenameForKey(e.Key)); } prunedFiles++; delDic.Add(pair.Key, pair.Value); if (mTotalSize + neededSpace < mMaxCacheSizeInBytes * HYSTERESIS_FACTOR) { break; } } foreach (KeyValuePair <string, CacheHeader> del in delDic) { mEntries.Remove(del.Key); } if (VolleyLog.DEBUG) { VolleyLog.V("Pruned {0} files,{1} bytes,{2} ms", prunedFiles, (mTotalSize - before), SystemClock.ElapsedRealtime() - startTime); } }
private void PutEntry(String key, CacheHeader entry) { if (!mEntries.ContainsKey(key)) { mTotalSize += entry.Size; } else { CacheHeader oldEntry = mEntries[key]; mTotalSize += (entry.Size - oldEntry.Size); } if (mEntries.ContainsKey(key)) { mEntries[key] = entry; } else { mEntries.Add(key, entry); } }
/// <summary> /// 从流中读取缓存相关信息 /// (当前只提供文件缓存所以是从文件中读取) /// </summary> public static CacheHeader ReadHeader(Stream input) { CacheHeader entry = new CacheHeader(); int magic = DiskBasedCache.ReadInt(input); if (magic != DiskBasedCache.CACHE_MAGIC) { throw new IOException(); } entry.Key = DiskBasedCache.ReadString(input); entry.ETag = DiskBasedCache.ReadString(input); if (String.IsNullOrEmpty(entry.ETag)) { entry.ETag = null; } entry.ServerDate = DiskBasedCache.ReadLong(input); entry.LastModified = DiskBasedCache.ReadLong(input); entry.Ttl = DiskBasedCache.ReadLong(input); entry.SoftTtl = DiskBasedCache.ReadLong(input); entry.ResponseHeaders = DiskBasedCache.ReadStringStringMap(input); return(entry); }
/// <summary> /// 获取缓存数据 /// </summary> public Entry Get(string key) { lock (this) { CacheHeader entry = null; mEntries.TryGetValue(key, out entry); if (entry == null) { return(null); } FileInfo file = GetFileForKey(key); FileStream fs = null; try { fs = file.Open(FileMode.OpenOrCreate); CacheHeader.ReadHeader(fs); byte[] data = StreamToBytes(fs, (int)(fs.Length - fs.Position)); return(entry.ToCacheEntry(data)); } catch (IOException e) { VolleyLog.D("{0}:{1}", file.FullName, e.ToString()); } finally { if (fs != null) { try { fs.Close(); } catch (IOException) { } } } return(null); } }
/// <summary> /// ������������ /// </summary> public void Put(string key, Entry entry) { lock (this) { PruneIfNeeded(entry.Data.Length); var file = GetFileForKey(key); try { var fos = file.Open(FileMode.OpenOrCreate); CacheHeader e = new CacheHeader(key, entry); bool success = e.WriteHeader(fos); if (!success) { fos.Close(); VolleyLog.D("Failed to write header for {0}", file.FullName); throw new IOException(); } fos.Write(entry.Data, 0, entry.Data.Length); fos.Close(); PutEntry(key, e); return; } catch (IOException) { } file.Delete(); if (File.Exists(file.FullName)) { VolleyLog.D("Could not clean up file {0}", file.FullName); } } }
/// <summary> /// �����ж�ȡ���������Ϣ /// ����ǰֻ�ṩ�ļ����������Ǵ��ļ��ж�ȡ�� /// </summary> public static CacheHeader ReadHeader(Stream input) { CacheHeader entry = new CacheHeader(); int magic = DiskBasedCache.ReadInt(input); if (magic != DiskBasedCache.CACHE_MAGIC) { throw new IOException(); } entry.Key = DiskBasedCache.ReadString(input); entry.ETag = DiskBasedCache.ReadString(input); if (String.IsNullOrEmpty(entry.ETag)) { entry.ETag = null; } entry.ServerDate = DiskBasedCache.ReadLong(input); entry.LastModified = DiskBasedCache.ReadLong(input); entry.Ttl = DiskBasedCache.ReadLong(input); entry.SoftTtl = DiskBasedCache.ReadLong(input); entry.ResponseHeaders = DiskBasedCache.ReadStringStringMap(input); return entry; }