You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在不重新分配内存的情况下从Memory<byte>获取MemoryStream或其他Stream实例

无需拷贝内存从Memory获取Stream实例的实现方案
  • 托管数组 backed 的Memory<byte>场景(最常用)
    绝大多数日常使用的Memory<byte>都基于托管数组分配,你可以通过MemoryMarshal.TryGetArray拿到对应的数组段,直接传给MemoryStream构造函数,该过程完全不会发生内存拷贝,Stream会直接操作原始数组的对应区间:

    Memory<byte> sourceMemory = GetYourMemoryInstance();
    if (MemoryMarshal.TryGetArray(sourceMemory, out ArraySegment<byte> segment))
    {
        // 直接使用原始数组构造MemoryStream,无内存拷贝
        Stream stream = new MemoryStream(segment.Array, segment.Offset, segment.Count, writable: true);
    }
    

    该方法返回的Stream完全兼容标准MemoryStream的所有用法,支持读写操作。

  • 非托管内存 backed 的Memory<byte>或者跨版本通用场景
    如果你的Memory<byte>来自非托管内存分配,无法拿到托管数组段,可以通过Pin住内存后构造UnmanagedMemoryStream实现零拷贝:

    unsafe
    {
        using var memoryHandle = sourceMemory.Pin();
        // 直接基于内存指针构造Stream,无内存拷贝
        Stream stream = new UnmanagedMemoryStream(
            (byte*)memoryHandle.Pointer, 
            sourceMemory.Length, 
            sourceMemory.Length, 
            FileAccess.ReadWrite);
    }
    

    需要注意必须保持memoryHandle的存活直到Stream使用完毕,避免内存被GC移动或者回收导致访问异常。如果是只读的ReadOnlyMemory<byte>,把FileAccess参数改为FileAccess.Read即可。

  • 低版本框架兼容场景(.NET Framework / .NET Core 2.x及以下)
    你可以自定义继承自Stream的实现类,内部持有Memory<byte>实例,重写Read、Write、Seek、Length、Position等核心方法,直接操作Memory<byte>的Span属性,全程不需要分配额外的缓冲区,即可实现零拷贝的Stream封装。

内容的提问来源于stack exchange,提问作者Perfect28

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 06:06:07