MemoryMappedFile的初级应用
阅读原文时间:2023年07月10日阅读:1
 public class SyncMemoryList<T>: SyncList<T>, IDisposable  
 {  
     private MemoryCache<T> \_memoryCache = new MemoryCache<T>();

     public new void Add(T item)  
     {  
         string json = $"{ToJson(item)}\\n";  
         WriteCache(json);

         base.Add(item);  
     }

     private string ToJson(T item)  
     {  
         Type type = typeof(T);  
         if (type.IsClass)  
             return JsonExtensions.ToJson(item);  
         else  
             return item.ToString();  
     }

     private void WriteCache(string text)  
     {  
         byte\[\] bytes = Encoding.UTF8.GetBytes(text);  
         if (\_memoryCache.IsAllowWrite(bytes.Length))  
         {  
             \_memoryCache.Write(bytes);  
         }  
         else  
         {  
             \_memoryCache.Dispose();  
             \_memoryCache = new MemoryCache<T>();  
             \_memoryCache.Write(bytes);  
         }  
     }

     #region IDisposable Support  
     private bool disposedValue = false; // 要检测冗余调用

     protected virtual void Dispose(bool disposing)  
     {  
         if (!disposedValue)  
         {  
             if (disposing)  
             {  
                 // TODO: 释放托管状态(托管对象)。  
             }

             \_memoryCache?.Dispose();  
             disposedValue = true;  
         }  
     }

     // TODO: 仅当以上 Dispose(bool disposing) 拥有用于释放未托管资源的代码时才替代终结器。  
     // ~SyncMemoryList() {  
     //   // 请勿更改此代码。将清理代码放入以上 Dispose(bool disposing) 中。  
     //   Dispose(false);  
     // }

     // 添加此代码以正确实现可处置模式。  
     public void Dispose()  
     {  
         // 请勿更改此代码。将清理代码放入以上 Dispose(bool disposing) 中。  
         Dispose(true);  
         // TODO: 如果在以上内容中替代了终结器,则取消注释以下行。  
         // GC.SuppressFinalize(this);  
     }  
     #endregion  
 }

 internal class MemoryCache<T>:IDisposable  
 {  
     private readonly MemoryMappedFile \_memoryMapped = null;  
     private readonly MemoryMappedViewStream \_stream = null;  
     private static readonly long \_defaultSize =  \* ;  
     private readonly long \_capatity = ;  
     public MemoryCache()  
     {  
         string mapname = $"{typeof(T).Name}";  
         string fileName = $"{typeof(T).Name}\_{DateTime.Now:yyyy\_M\_d}.dat";  
         long maxlen = ;  
         if (File.Exists(fileName))  
         {  
             (long size,long offset) = (, );  
             FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);  
             (size,offset) = GetFileInfo(stream);  
             //stream.Close();  
             maxlen = size + \_defaultSize;  
             \_memoryMapped = MemoryMappedFile.CreateFromFile(stream, mapname, maxlen, MemoryMappedFileAccess.ReadWrite, HandleInheritability.None, false);  
             \_stream = \_memoryMapped.CreateViewStream();  
             \_stream.Position = offset ==  ?  : offset;  
         }  
         else  
         {  
             maxlen = \_defaultSize + ;  
             \_memoryMapped = MemoryMappedFile.CreateFromFile(fileName, FileMode.OpenOrCreate, mapname, maxlen, MemoryMappedFileAccess.ReadWrite);  
             \_stream = \_memoryMapped.CreateViewStream();  
             \_stream.Position = ;  
         }

         \_capatity = maxlen - ;  
     }

     public long Position => \_stream.Position;

     private (long, long) GetFileInfo(Stream stream)  
     {  
         try  
         {  
             byte\[\] byteSize = new byte\[\];  
             byte\[\] byteOffset = new byte\[\];

             stream.Read(byteSize, , byteSize.Length);  
             stream.Read(byteOffset, , byteOffset.Length);

             return (BitConverter.ToInt64(byteSize, ), BitConverter.ToInt64(byteOffset, ));  
         }  
         catch (Exception e)  
         {  
             return (\_defaultSize, );  
         }  
     }

     public bool IsAllowWrite(long size)  
     {  
         return \_capatity - \_stream.Position > size;  
     }

     public void WriteLength(long offset)  
     {  
         byte\[\] byteSize = BitConverter.GetBytes(\_capatity);  
         byte\[\] byteOffset = BitConverter.GetBytes(offset);  
         \_stream.Position = ;  
         \_stream.Write(byteSize, , byteSize.Length);  
         \_stream.Write(byteOffset, , byteOffset.Length);  
     }

     public void Write(byte\[\] bytes)  
     {  
         var \_offset = \_stream.Position;  
         WriteLength(\_offset + bytes.Length);  
         \_stream.Position = \_offset;  
         \_stream.Write(bytes, , bytes.Length);  
     }

     public void Dispose()  
     {  
         \_memoryMapped?.Dispose();  
         \_stream?.Dispose();  
     }  
 }

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章