/// <summary> /// 从内存文件映射中,分段创建一个读写的流 /// </summary> /// <param name="offset">读写的起始偏移</param> /// <param name="count">总映射的数量,建议映射的数量少于1G</param> /// <returns>返回一个读写流</returns> public MemoryMappingFileStream CreateMappingStream(long offset, long count) { var readCount = Math.Min(count, fileLength - offset); var realOffsetValue = offset - offset % systemAllocMin; //计算出所需的真实起始偏移 var baseOffset = 0L; if (offset < systemAllocMin) { baseOffset = offset; readCount += offset; } uint dwFileOffsetLow = (uint)(realOffsetValue & 0xffffffffL); uint dwFileOffsetHigh = (uint)(realOffsetValue >> 0x20); IntPtr lpbMapAddress = UnManageAPI.MapViewOfFile(targetMappingFileHandle, UnManageAPI.FILE_MAP_COPY | UnManageAPI.FILE_MAP_READ | UnManageAPI.FILE_MAP_WRITE, dwFileOffsetHigh, dwFileOffsetLow, (uint)readCount); if (lpbMapAddress == IntPtr.Zero) { throw new IOException("无法映射指定的偏移"); } return(new MemoryMappingFileStream(lpbMapAddress, baseOffset, readCount - baseOffset)); }
private void OpenFile(string fileName) { if (!File.Exists(fileName)) { throw new FileNotFoundException(); } IntPtr fileHandle = UnManageAPI.CreateFile(fileName, UnManageAPI.GENERIC_READ | UnManageAPI.GENERIC_WRITE, FileShare.Read | FileShare.Write, IntPtr.Zero, FileMode.Open, UnManageAPI.FILE_ATTRIBUTE_NORMAL | UnManageAPI.FILE_FLAG_SEQUENTIAL_SCAN, IntPtr.Zero); if (UnManageAPI.INVALID_HANDLE_VALUE == (int)fileHandle) { throw new FileLoadException("文件打开出错"); } uint fileSizeHigh = 0; //读取文件大小 long fileSize = UnManageAPI.GetFileSize(fileHandle, out fileSizeHigh); IntPtr mappingFileHandle = UnManageAPI.CreateFileMapping(fileHandle, IntPtr.Zero, UnManageAPI.PAGE_READWRITE, 0, 0, "KugarMapping"); if (mappingFileHandle == IntPtr.Zero) { throw new FileLoadException("文件映射出错"); } fileSize |= (((uint)fileSizeHigh) << 32); UnManageAPI.CloseHandle(fileHandle); targetMappingFileHandle = mappingFileHandle; fileLength = fileSize; }
protected override void Dispose(bool disposing) { base.Dispose(disposing); if (disposing) { UnManageAPI.UnmapViewOfFile(_mappingAddress); } }
public override void Flush() { var tempMappingLength = Interlocked.Read(ref _mappingLength); Interlocked.Add(ref tempMappingLength, _baseOffset); UnManageAPI.FlushViewOfFile(_mappingAddress, (int)tempMappingLength); //return false; }
public MemoryMappingFile(string fileName) { var sysInf = new UnManageAPI.SYSTEM_INFO(); UnManageAPI.GetSystemInfo(ref sysInf); if (systemAllocMin == 0L) { systemAllocMin = sysInf.dwAllocationGranularity; } OpenFile(fileName); }
protected void Disposed(bool disposing) { if (_isDispose) { return; } if (disposing) { UnManageAPI.CloseHandle(targetMappingFileHandle); _isDispose = true; } }