csharp/acarteas/FileCache/src/FileCache/FileCacheManager.cs

FileCacheManager.cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading;

namespace System.Runtime.Caching
{
    public abstract clast FileCacheManager
    {
        // Magic version for new sysfiles: 3.3.0 packed into a long.
        protected const ulong CACHE_VERSION = (  3  0; i--) // try 5 times to read the file, if we can't, give up
                {
                    try
                    {
                        using (FileStream stream = GetStream(path, FileMode.Open, FileAccess.Read, FileShare.Read))
                        {
                            using(BinaryReader reader = new BinaryReader(stream))
                            {
                                try
                                {
                                    // The old "BinaryFormatter" sysfiles will fail this check.
                                    if (HeaderVersionValid(reader))
                                    {
                                        value = reader.ReadInt64();
                                    }
                                    else
                                    {
                                        // Invalid version - return invalid value & failure.
                                        value = long.MinValue;
                                        success = false;
                                        break;
                                    }
                                }
                                catch (Exception)
                                {
                                    value = long.MinValue;
                                    // DriveCommerce: Need to rethrow to get the IOException caught.
                                    throw;
                                }
                            }
                            success = true;
                            break;
                        }
                    }
                    catch (IOException)
                    {
                        // we timed out... so try again
                    }
                }
            }

            // `value` already set correctly.
            return success;
        }

        /// 
        /// Read a `DateTime` struct from a sysfile using `DateTime.FromBinary()`.
        /// 
        /// The name of the sysfile (without directory)
        /// The value read or DateTime.MinValue
        /// success/failure boolean
        public bool ReadSysValue(string filename, out DateTime value)
        {
            // DateTime is serialized as a long, so use that `ReadSysValue()` function.
            long serialized;
            if (ReadSysValue(filename, out serialized))
            {
                value = DateTime.FromBinary(serialized);
                return true;
            }
            // else failed:
            value = DateTime.MinValue;
            return false;
        }

        /// 
        /// Generic version of `WriteSysValue` just throws an ArgumentException on unknown new types.
        /// 
        /// The name of the sysfile (without directory)
        /// The data to write to the sysfile
        public void WriteSysValue(string filename, T data) where T : struct
        {
            throw new ArgumentException(string.Format("Type is currently unsupported: {0}", typeof(T).ToString()), "data");
        }

        /// 
        /// Writes a long to a system file that is not part of the cache itself,
        /// but is used to help it function.
        /// 
        /// The name of the sysfile (without directory)
        /// The long to write to the file
        public void WriteSysValue(string filename, long data)
        {
            // sys files go in the root directory
            string path = Path.Combine(CacheDir, filename);

            // write the data to the file
            using (FileStream stream = GetStream(path, FileMode.Create, FileAccess.Write, FileShare.Write))
            {
                using (BinaryWriter writer = new BinaryWriter(stream))
                {
                    // Must write the magic version header first.
                    HeaderVersionWrite(writer);

                    writer.Write(data);
                }
            }
        }

        /// 
        /// Writes a long to a system file that is not part of the cache itself,
        /// but is used to help it function.
        /// 
        /// The name of the sysfile (without directory)
        /// The DateTime to write to the file
        public void WriteSysValue(string filename, DateTime data)
        {
            // Convert to long and use long's function.
            WriteSysValue(filename, data.ToBinary());
        }

        /// 
        /// This function servies to centralize file stream access within this clast.
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        protected FileStream GetStream(string path, FileMode mode, FileAccess access, FileShare share)
        {
            FileStream stream = null;
            TimeSpan interval = new TimeSpan(0, 0, 0, 0, 50);
            TimeSpan totalTime = new TimeSpan();
            while (stream == null)
            {
                try
                {
                    stream = File.Open(path, mode, access, share);
                }
                catch (IOException ex)
                {
                    Thread.Sleep(interval);
                    totalTime += interval;

                    //if we've waited too long, throw the original exception.
                    if (AccessTimeout.Ticks != 0)
                    {
                        if (totalTime > AccessTimeout)
                        {
                            throw ex;
                        }
                    }
                }
            }
            return stream;
        }

        /// 
        /// Deletes the specified key/region combo.  Returns bytes freed from delete.
        /// 
        /// 
        /// 
        /// 
        public virtual long DeleteFile(string key, string regionName = null)
        {
            long bytesFreed = 0;

            // Because of the possibility of multiple threads accessing this, it's possible that
            // while we're trying to remove something, another thread has already removed it.
            try
            {
                FileCachePayload fcp = ReadFile(FileCache.PayloadMode.Filename, key, regionName);
                string path = GetCachePath(key, regionName);
                bytesFreed -= new FileInfo(path).Length;
                File.Delete(path);

                //remove policy file
                string cachedPolicy = GetPolicyPath(key, regionName);
                bytesFreed -= new FileInfo(cachedPolicy).Length;
                File.Delete(cachedPolicy);
            }
            catch (IOException ex)
            {
                //Owning FC might be interested in this exception.
                throw ex;
            }
            return Math.Abs(bytesFreed);
        }

        protected clast LocalCacheBinder : System.Runtime.Serialization.SerializationBinder
        {
            public override Type BindToType(string astemblyName, string typeName)
            {
                Type typeToDeserialize = null;

                String currentastembly = astembly.Getastembly(typeof(LocalCacheBinder)).FullName;
                astemblyName = currentastembly;

                // Get the type using the typeName and astemblyName
                typeToDeserialize = Type.GetType(String.Format("{0}, {1}",
                                                               typeName, astemblyName));

                return typeToDeserialize;
            }
        }
    }
}