可以在 Windows 和 Linux 上运行,利用了 .NET Core 的 System.IO.MemoryMappedFiles
库。这个类实现了共享内存的创建、打开、读取和写入功能。以下是对代码的一些分析和建议改进。
代码分析
初始化与打开共享内存:
Init
方法用于创建新的共享内存段。OpenMem
方法用于打开已存在的共享内存段。- 这两个方法都处理了异常并返回状态码,非常适合用于错误处理。
关闭共享内存:
Close
方法确保释放资源,避免内存泄漏。
读写数据:
Read
和Write
方法提供了数据读写的功能,支持指定偏移量和大小。
状态管理:
_isInitialized
和_isOpened
标志用于跟踪共享内存的状态。
using System;
using System.IO.MemoryMappedFiles;
using System.Runtime.InteropServices;
namespace MemoryDB
{
class Class_ShareMemory
{
private MemoryMappedFile _memoryMappedFile;
private MemoryMappedViewAccessor _viewAccessor;
private long _memSize;
private string _name;
private bool _isInitialized;
private bool _isOpened;
public Class_ShareMem()
{
_isInitialized = false;
_isOpened = false;
}
/// <summary>
/// 初始化共享内存
/// </summary>
/// <param name="name">共享内存名称</param>
/// <param name="size">共享内存大小</param>
/// <returns></returns>
public int Init(string name, long size)
{
if (size <= 0) size = 0x00800000; // Default size
_memSize = size;
_name = name;
try
{
// 根据操作系统设置共享内存名称
string fullName = GetFullMemoryMappedFileName(_name);
_memoryMappedFile = MemoryMappedFile.CreateNew(fullName, _memSize);
_viewAccessor = _memoryMappedFile.CreateViewAccessor();
_isInitialized = true;
}
catch (Exception ex)
{
Console.WriteLine($"创建共享内存失败: {ex.Message}");
return 2; // 创建失败
}
return 0; // 创建成功
}
/// <summary>
/// 打开共享内存
/// </summary>
public int OpenMem(string name, long size)
{
if (size <= 0) size = 0x00800000; // Default size
_memSize = size;
_name = name;
try
{
// 根据操作系统设置共享内存名称
string fullName = GetFullMemoryMappedFileName(_name);
_memoryMappedFile = MemoryMappedFile.OpenExisting(fullName);
_viewAccessor = _memoryMappedFile.CreateViewAccessor();
_isOpened = true;
}
catch (Exception ex)
{
Console.WriteLine($"打开共享内存失败: {ex.Message}");
return 1; // 打开失败
}
return 0; // 打开成功
}
/// <summary>
/// 关闭共享内存
/// </summary>
public void Close()
{
_viewAccessor?.Dispose();
_memoryMappedFile?.Dispose();
_isInitialized = false;
_isOpened = false;
}
/// <summary>
/// 读数据
/// </summary>
/// <param name="data">数据</param>
/// <param name="offset">起始地址</param>
/// <param name="size">个数</param>
/// <returns></returns>
public int Read(ref byte[] data, long offset, int size)
{
if (offset + size > _memSize) return 2; // 超出数据区
if (_isInitialized || _isOpened)
{
_viewAccessor.ReadArray(offset, data, 0, size);
}
else
{
return 1; // 共享内存未初始化
}
return 0; // 读成功
}
/// <summary>
/// 写数据
/// </summary>
/// <param name="data">数据</param>
/// <param name="offset">起始地址</param>
/// <param name="size">个数</param>
/// <returns></returns>
public int Write(byte[] data, long offset, int size)
{
if (offset + size > _memSize) return 2; // 超出数据区
if (_isInitialized || _isOpened)
{
_viewAccessor.WriteArray(offset, data, 0, size);
}
else
{
return 1; // 共享内存未初始化
}
return 0; // 写成功
}
/// <summary>
/// 根据操作系统获取完整的共享内存名称
/// </summary>
/// <param name="name">共享内存名称</param>
/// <returns>完整的共享内存名称</returns>
private string GetFullMemoryMappedFileName(string name)
{
// 在 Windows 中使用 Global 前缀,在 Linux 中不使用
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
return $"Global\\{name}";
}
else
{
return name; // Linux 上直接使用名称
}
}
}
}