public override object AddOrGetExisting(string key, object value, CacheItemPolicy policy, string regionName = null) { string path = GetCachePath(key, regionName); object oldData = null; //pull old value if it exists if (File.Exists(path)) { try { oldData = Get(key, regionName); } catch (Exception) { oldData = null; } } SerializableCacheItemPolicy cachePolicy = new SerializableCacheItemPolicy(policy); FileCachePayload newPayload = new FileCachePayload(value, cachePolicy); WriteFile(key, newPayload, regionName); //As documented in the spec (http://msdn.microsoft.com/en-us/library/dd780602.aspx), return the old //cached value or null return(oldData); }
/// <summary> /// Returns a list of keys for a given region. /// </summary> /// <param name="regionName"></param> public override IEnumerable <string> GetKeys(string regionName = null) { string region = ""; if (string.IsNullOrEmpty(regionName) == false) { region = regionName; } string directory = Path.Combine(CacheDir, PolicySubFolder, region); List <string> keys = new List <string>(); if (Directory.Exists(directory)) { foreach (string file in Directory.GetFiles(directory)) { try { SerializableCacheItemPolicy policy = Deserialize(file) as SerializableCacheItemPolicy; keys.Add(policy.Key); } catch { } } } return(keys.ToArray()); }
/// <summary> /// Because hash collisions prevent us from knowing the exact file name of the supplied key, we need to probe through /// all possible fine name combinations. This function is used internally by the Delete and Get functions in this class. /// </summary> /// <param name="key"></param> /// <param name="regionName"></param> /// <returns></returns> private string GetFileName(string key, string regionName = null) { if (regionName == null) { regionName = ""; } //CacheItemPolicies have references to the original key, which is why we look there. This implies that //manually deleting a policy in the file system has dire implications for any keys that probe after //the policy. It also means that deleting a policy file makes the related .dat "invisible" to FC. string directory = Path.Combine(CacheDir, PolicySubFolder, regionName); string hash = key.GetHashCode().ToString(); int hashCounter = 0; string fileName = Path.Combine(directory, string.Format("{0}_{1}.policy", hash, hashCounter)); bool found = false; while (found == false) { fileName = Path.Combine(directory, string.Format("{0}_{1}.policy", hash, hashCounter)); if (File.Exists(fileName) == true) { //check for correct key try { SerializableCacheItemPolicy policy = Deserialize(fileName) as SerializableCacheItemPolicy; if (key.CompareTo(policy.Key) == 0) { //correct key found! found = true; } else { //wrong key, try again hashCounter++; } } catch { //Corrupt file? Assume usable for current key. found = true; } } else { //key not found, must not exist. Return last generated file name. found = true; } } return(Path.GetFileNameWithoutExtension(fileName)); }
/// <summary> /// This function serves to centralize file reads within this class. /// </summary> /// <param name="path"></param> /// <param name="objectBinder"></param> /// <returns></returns> private FileCachePayload ReadFile(string key, string regionName = null, SerializationBinder objectBinder = null) { object data = null; SerializableCacheItemPolicy policy = new SerializableCacheItemPolicy(); string cachePath = GetCachePath(key, regionName); string policyPath = GetPolicyPath(key, regionName); FileCachePayload payload = new FileCachePayload(null); if (File.Exists(cachePath)) { using (FileStream stream = GetStream(cachePath, FileMode.Open, FileAccess.Read)) { BinaryFormatter formatter = new BinaryFormatter(); //AC: From http://spazzarama.com//2009/06/25/binary-deserialize-unable-to-find-assembly/ // Needed to deserialize custom objects if (objectBinder != null) { //take supplied binder over default binder formatter.Binder = objectBinder; } else if (_binder != null) { formatter.Binder = _binder; } try { data = formatter.Deserialize(stream); } catch (SerializationException) { data = null; } finally { stream.Close(); } } } if (File.Exists(policyPath)) { using (FileStream stream = GetStream(policyPath, FileMode.Open, FileAccess.Read)) { BinaryFormatter formatter = new BinaryFormatter(); formatter.Binder = new LocalCacheBinder(); try { policy = formatter.Deserialize(stream) as SerializableCacheItemPolicy; } catch (SerializationException) { policy = new SerializableCacheItemPolicy(); } finally { stream.Close(); } } } payload.Payload = data; payload.Policy = policy; return(payload); }