using System; using System.IO; using System.IO.MemoryMappedFiles; namespace XGame.Framework.Logger { struct MMFileHeader { public int position; public int length; public readonly static int PositionIndex = 0; public readonly static int LengthIndex = PositionIndex + sizeof(int); public readonly static int FileIndex = LengthIndex + sizeof(int); public readonly static int ContextIndex = FileIndex; } class MMFile : IDisposable { private MemoryMappedFile _mmf; private MemoryMappedViewAccessor _accessor; public MMFile(string path, uint capacity = 2048) { try { if (!File.Exists(path)) { using (var filesteam = File.Create(path)) { filesteam.SetLength(capacity); _mmf = MemoryMappedFile.CreateFromFile(filesteam, null, capacity, MemoryMappedFileAccess.ReadWrite, HandleInheritability.None, true); } } else { using (var filesteam = File.Open(path, FileMode.Open, FileAccess.ReadWrite)) { filesteam.SetLength(capacity); _mmf = MemoryMappedFile.CreateFromFile(filesteam, null, capacity, MemoryMappedFileAccess.ReadWrite, HandleInheritability.None, true); } } _accessor = _mmf.CreateViewAccessor(0, capacity, MemoryMappedFileAccess.ReadWrite); var header = ReadHeader(); header.length = (int)capacity; WriteHeader(header); } catch(System.Exception e) { UnityEngine.Debug.LogException(e); } } public MMFileHeader ReadHeader() { if (_accessor == null) throw new Exception("存取器尚未初始化!!!"); var header = new MMFileHeader(); header.position = _accessor.ReadInt32(0); header.length = _accessor.ReadInt32(4); return header; } public void WriteHeader(MMFileHeader header) { if (_accessor == null) throw new Exception("存取器尚未初始化!!!"); _accessor.Write(MMFileHeader.PositionIndex, header.position); _accessor.Write(MMFileHeader.LengthIndex, header.length); } public byte[] ReadAll() { if (_accessor == null) throw new Exception("存取器尚未初始化!!!"); var header = ReadHeader(); var result = new byte[header.position]; _accessor.ReadArray(MMFileHeader.ContextIndex, result, 0, header.position); return result; } public bool Write(byte[] souces, int offset, int length) { if (_accessor == null) throw new System.Exception("存取器尚未初始化"); if (!_accessor.CanWrite) throw new System.Exception("存取器禁止写入"); var header = ReadHeader(); var absolutePosition = header.position + MMFileHeader.ContextIndex; if (absolutePosition + length > header.length) { //var overflow = absolutePosition + length - header.length; //throw new MMFileOverflowException(overflow, "写入溢出!"); return false; } _accessor.WriteArray(absolutePosition, souces, offset, length); header.position += length; WriteHeader(header); return true; } public void Reset() { var header = ReadHeader(); header.position = 0; WriteHeader(header); } public void Dispose() { _accessor?.Dispose(); _mmf?.Dispose(); } } }