MemoryMappedFile的初级应用

  1     public class SyncMemoryList<T>: SyncList<T>, IDisposable
  2     {
  3         private MemoryCache<T> _memoryCache = new MemoryCache<T>();
  4 
  5         public new void Add(T item)
  6         {
  7             string json = $"{ToJson(item)}\n";
  8             WriteCache(json);
  9 
 10             base.Add(item);
 11         }
 12 
 13         private string ToJson(T item)
 14         {
 15             Type type = typeof(T);
 16             if (type.IsClass)
 17                 return JsonExtensions.ToJson(item);
 18             else
 19                 return item.ToString();
 20         }
 21 
 22         private void WriteCache(string text)
 23         {
 24             byte[] bytes = Encoding.UTF8.GetBytes(text);
 25             if (_memoryCache.IsAllowWrite(bytes.Length))
 26             {
 27                 _memoryCache.Write(bytes);
 28             }
 29             else
 30             {
 31                 _memoryCache.Dispose();
 32                 _memoryCache = new MemoryCache<T>();
 33                 _memoryCache.Write(bytes);
 34             }
 35         }
 36 
 37         #region IDisposable Support
 38         private bool disposedValue = false; // 要检测冗余调用
 39 
 40         protected virtual void Dispose(bool disposing)
 41         {
 42             if (!disposedValue)
 43             {
 44                 if (disposing)
 45                 {
 46                     // TODO: 释放托管状态(托管对象)。
 47                 }
 48 
 49                 _memoryCache?.Dispose();
 50                 disposedValue = true;
 51             }
 52         }
 53 
 54         // TODO: 仅当以上 Dispose(bool disposing) 拥有用于释放未托管资源的代码时才替代终结器。
 55         // ~SyncMemoryList() {
 56         //   // 请勿更改此代码。将清理代码放入以上 Dispose(bool disposing) 中。
 57         //   Dispose(false);
 58         // }
 59 
 60         // 添加此代码以正确实现可处置模式。
 61         public void Dispose()
 62         {
 63             // 请勿更改此代码。将清理代码放入以上 Dispose(bool disposing) 中。
 64             Dispose(true);
 65             // TODO: 如果在以上内容中替代了终结器,则取消注释以下行。
 66             // GC.SuppressFinalize(this);
 67         }
 68         #endregion
 69     }
 70 
 71     internal class MemoryCache<T>:IDisposable
 72     {
 73         private readonly MemoryMappedFile _memoryMapped = null;
 74         private readonly MemoryMappedViewStream _stream = null;
 75         private static readonly long _defaultSize = 1024 * 1024;
 76         private readonly long _capatity = 0;
 77         public MemoryCache()
 78         {
 79             string mapname = $"{typeof(T).Name}";
 80             string fileName = $"{typeof(T).Name}_{DateTime.Now:yyyy_M_d}.dat";
 81             long maxlen = 0;
 82             if (File.Exists(fileName))
 83             {
 84                 (long size,long offset) = (0, 0);
 85                 FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
 86                 (size,offset) = GetFileInfo(stream);
 87                 //stream.Close();
 88                 maxlen = size + _defaultSize;
 89                 _memoryMapped = MemoryMappedFile.CreateFromFile(stream, mapname, maxlen, MemoryMappedFileAccess.ReadWrite, HandleInheritability.None, false);
 90                 _stream = _memoryMapped.CreateViewStream();
 91                 _stream.Position = offset == 0 ? 16 : offset;
 92             }
 93             else
 94             {
 95                 maxlen = _defaultSize + 16;
 96                 _memoryMapped = MemoryMappedFile.CreateFromFile(fileName, FileMode.OpenOrCreate, mapname, maxlen, MemoryMappedFileAccess.ReadWrite);
 97                 _stream = _memoryMapped.CreateViewStream();
 98                 _stream.Position = 16;
 99             }
100 
101             _capatity = maxlen - 16;
102         }
103 
104         public long Position => _stream.Position;
105 
106         private (long, long) GetFileInfo(Stream stream)
107         {
108             try
109             {
110                 byte[] byteSize = new byte[8];
111                 byte[] byteOffset = new byte[8];
112 
113                 stream.Read(byteSize, 0, byteSize.Length);
114                 stream.Read(byteOffset, 0, byteOffset.Length);
115 
116                 return (BitConverter.ToInt64(byteSize, 0), BitConverter.ToInt64(byteOffset, 0));
117             }
118             catch (Exception e)
119             {
120                 return (_defaultSize, 0);
121             }
122         }
123 
124         public bool IsAllowWrite(long size)
125         {
126             return _capatity - _stream.Position > size;
127         }
128 
129         public void WriteLength(long offset)
130         {
131             byte[] byteSize = BitConverter.GetBytes(_capatity);
132             byte[] byteOffset = BitConverter.GetBytes(offset);
133             _stream.Position = 0;
134             _stream.Write(byteSize, 0, byteSize.Length);
135             _stream.Write(byteOffset, 0, byteOffset.Length);
136         }
137 
138         public void Write(byte[] bytes)
139         {
140             var _offset = _stream.Position;
141             WriteLength(_offset + bytes.Length);
142             _stream.Position = _offset;
143             _stream.Write(bytes, 0, bytes.Length);
144         }
145 
146         public void Dispose()
147         {
148             _memoryMapped?.Dispose();
149             _stream?.Dispose();
150         }
151     }

 

posted @ 2018-05-23 12:44  沉迷代码的萌新  阅读(282)  评论(0编辑  收藏  举报