MMFile.cs 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. using System;
  2. using System.IO;
  3. using System.IO.MemoryMappedFiles;
  4. namespace XGame.Framework.Logger
  5. {
  6. struct MMFileHeader
  7. {
  8. public int position;
  9. public int length;
  10. public readonly static int PositionIndex = 0;
  11. public readonly static int LengthIndex = PositionIndex + sizeof(int);
  12. public readonly static int FileIndex = LengthIndex + sizeof(int);
  13. public readonly static int ContextIndex = FileIndex;
  14. }
  15. class MMFile : IDisposable
  16. {
  17. private MemoryMappedFile _mmf;
  18. private MemoryMappedViewAccessor _accessor;
  19. public MMFile(string path, uint capacity = 2048)
  20. {
  21. try
  22. {
  23. if (!File.Exists(path))
  24. {
  25. using (var filesteam = File.Create(path))
  26. {
  27. filesteam.SetLength(capacity);
  28. _mmf = MemoryMappedFile.CreateFromFile(filesteam, null, capacity, MemoryMappedFileAccess.ReadWrite, HandleInheritability.None, true);
  29. }
  30. }
  31. else
  32. {
  33. using (var filesteam = File.Open(path, FileMode.Open, FileAccess.ReadWrite))
  34. {
  35. filesteam.SetLength(capacity);
  36. _mmf = MemoryMappedFile.CreateFromFile(filesteam, null, capacity, MemoryMappedFileAccess.ReadWrite, HandleInheritability.None, true);
  37. }
  38. }
  39. _accessor = _mmf.CreateViewAccessor(0, capacity, MemoryMappedFileAccess.ReadWrite);
  40. var header = ReadHeader();
  41. header.length = (int)capacity;
  42. WriteHeader(header);
  43. }
  44. catch(System.Exception e)
  45. {
  46. UnityEngine.Debug.LogException(e);
  47. }
  48. }
  49. public MMFileHeader ReadHeader()
  50. {
  51. if (_accessor == null)
  52. throw new Exception("存取器尚未初始化!!!");
  53. var header = new MMFileHeader();
  54. header.position = _accessor.ReadInt32(0);
  55. header.length = _accessor.ReadInt32(4);
  56. return header;
  57. }
  58. public void WriteHeader(MMFileHeader header)
  59. {
  60. if (_accessor == null)
  61. throw new Exception("存取器尚未初始化!!!");
  62. _accessor.Write(MMFileHeader.PositionIndex, header.position);
  63. _accessor.Write(MMFileHeader.LengthIndex, header.length);
  64. }
  65. public byte[] ReadAll()
  66. {
  67. if (_accessor == null)
  68. throw new Exception("存取器尚未初始化!!!");
  69. var header = ReadHeader();
  70. var result = new byte[header.position];
  71. _accessor.ReadArray(MMFileHeader.ContextIndex, result, 0, header.position);
  72. return result;
  73. }
  74. public bool Write(byte[] souces, int offset, int length)
  75. {
  76. if (_accessor == null)
  77. throw new System.Exception("存取器尚未初始化");
  78. if (!_accessor.CanWrite)
  79. throw new System.Exception("存取器禁止写入");
  80. var header = ReadHeader();
  81. var absolutePosition = header.position + MMFileHeader.ContextIndex;
  82. if (absolutePosition + length > header.length)
  83. {
  84. //var overflow = absolutePosition + length - header.length;
  85. //throw new MMFileOverflowException(overflow, "写入溢出!");
  86. return false;
  87. }
  88. _accessor.WriteArray(absolutePosition, souces, offset, length);
  89. header.position += length;
  90. WriteHeader(header);
  91. return true;
  92. }
  93. public void Reset()
  94. {
  95. var header = ReadHeader();
  96. header.position = 0;
  97. WriteHeader(header);
  98. }
  99. public void Dispose()
  100. {
  101. _accessor?.Dispose();
  102. _mmf?.Dispose();
  103. }
  104. }
  105. }