/// <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); } } }
public void Finish(String tag) { if (mRequestQueue != null) { mRequestQueue.Finish(this); } if (MarkerLog.ENABLED) { long threadId = Java.Lang.Thread.CurrentThread().Id; if (Looper.MyLooper() != Looper.MainLooper) { Handler mainThread = new Handler(Looper.MainLooper); mainThread.Post(() => { mEventLog.Add(tag, threadId); mEventLog.Finish(this.ToString()); }); return; } mEventLog.Add(tag, threadId); mEventLog.Finish(this.ToString()); } else { long requestTime = SystemClock.ElapsedRealtime() - mRequestBirthTime; if (requestTime >= SLOW_REQUEST_THRESHOLD_MS) { VolleyLog.D("{0} ms:{1}", requestTime, this.ToString()); } } }
/// <summary> /// 输出请求完成的信息(仅限调试) /// </summary> private void LogSlowRequests(long requestLifetime, Request request, byte[] responseContents, HttpStatusCode statusCode) { if (DEBUG || requestLifetime > SLOW_REQUEST_THRESHOLD_MS) { VolleyLog.D("HTTP response for request=<{0}> [lifetime={1}],[size={2}], [rc={3}],[retryCount={4}]", requestLifetime, requestLifetime, responseContents != null ? responseContents.Length.ToString() : "null", statusCode, request.GetRetryPolicy().CurrentRetryCount); } }
/// <summary> /// 删除缓存数据 /// </summary> public void Remove(string key) { lock (this) { var fi = GetFileForKey(key); fi.Delete(); RemoveEntry(key); if (File.Exists(fi.FullName)) { VolleyLog.D("Could not delete cache entry for key={0},filename={1}", key, fi.FullName); } } }
/// <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); } }
/// <summary> /// 清除缓存 /// </summary> public void Clear() { lock (this) { FileInfo[] files = mRootDirectory.GetFiles(); if (files != null) { foreach (FileInfo file in files) { file.Delete(); } } mEntries.Clear(); mTotalSize = 0; VolleyLog.D("Cache cleared."); } }
/// <summary> /// 将缓存信息写入流中 /// </summary> public bool WriteHeader(Stream output) { try { DiskBasedCache.WriteInt(output, DiskBasedCache.CACHE_MAGIC); DiskBasedCache.WriteString(output, Key); DiskBasedCache.WriteString(output, ETag == null ? "" : ETag); DiskBasedCache.WriteLong(output, ServerDate); DiskBasedCache.WriteLong(output, LastModified); DiskBasedCache.WriteLong(output, Ttl); DiskBasedCache.WriteLong(output, SoftTtl); DiskBasedCache.WriteStringStringMap(ResponseHeaders, output); output.Flush(); return(true); } catch (Exception e) { VolleyLog.D("{0}", e.ToString()); return(false); } }
/// <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); } }