C#如何使用MemoryStream在内存中进行流操作

来源:草根站长作者:坚哥头衔:草根站长
导读:本期聚焦于小伙伴创作的《C#如何使用MemoryStream在内存中进行流操作》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《C#如何使用MemoryStream在内存中进行流操作》有用,将其分享出去将是对创作者最好的鼓励。

在C#的开发场景中,经常需要处理数据的流式读写,当不需要将数据持久化到磁盘,仅需要在内存中完成流操作时,MemoryStream就是非常合适的选择。它继承自Stream类,所有数据都存储在内存缓冲区中,操作效率远高于磁盘流。

C#如何使用MemoryStream在内存中进行流操作

MemoryStream基础概念

MemoryStream是System.IO命名空间下的一个类,用于在内存中创建和操作流。它的核心特点是不依赖外部存储设备,所有读写操作都在内存的字节数组中完成,因此速度非常快,适合临时存储和处理数据。

MemoryStream的常用属性包括:

  • CanRead:指示当前流是否支持读取操作
  • CanWrite:指示当前流是否支持写入操作
  • Length:获取流中数据的总长度,单位为字节
  • Position:获取或设置当前流中的读取或写入位置
  • Capacity:获取或设置流的内存缓冲区容量

MemoryStream常用方法

MemoryStream提供了和Stream基类一致的常用方法,以下是开发中最常使用的几个:

  • Write(byte[] buffer, int offset, int count):将字节数组的数据写入流中
  • Read(byte[] buffer, int offset, int count):从流中读取指定长度的字节到字节数组
  • Seek(long offset, SeekOrigin origin):设置流的当前位置
  • ToArray():将流中的所有数据复制到新的字节数组中
  • GetBuffer():返回流底层的内存缓冲区引用(需要注意缓冲区可能未完全使用)
  • Flush():清除流的缓冲区,将所有缓冲数据写入基础设备(内存流中此操作无实际效果)
  • Close()/Dispose():释放流占用的资源,建议配合using语句使用

基础使用示例

写入和读取字符串数据

最常见的场景是将字符串转换为字节写入MemoryStream,再从流中读取还原为字符串:

using System;
using System.IO;
using System.Text;

class Program
{
    static void Main()
    {
        // 要写入的字符串
        string content = "这是一段测试文本,用于演示MemoryStream的基础操作";
        // 将字符串转换为字节数组,使用UTF8编码
        byte[] writeBytes = Encoding.UTF8.GetBytes(content);
        
        // 使用using语句自动释放MemoryStream资源
        using (MemoryStream ms = new MemoryStream())
        {
            // 将字节数组写入流
            ms.Write(writeBytes, 0, writeBytes.Length);
            // 将流的位置重置到开头,方便后续读取
            ms.Seek(0, SeekOrigin.Begin);
            
            // 创建读取用的字节数组,长度为流的长度
            byte[] readBytes = new byte[ms.Length];
            // 从流中读取数据到字节数组
            int readCount = ms.Read(readBytes, 0, readBytes.Length);
            // 将读取的字节数组转换为字符串
            string result = Encoding.UTF8.GetString(readBytes, 0, readCount);
            
            Console.WriteLine("读取到的内容:" + result);
        }
    }
}

直接获取流中的字节数组

如果需要直接获取MemoryStream中存储的所有数据,可以使用ToArray方法:

using System;
using System.IO;
using System.Text;

class Program
{
    static void Main()
    {
        string data = "测试ToArray方法的使用";
        byte[] sourceBytes = Encoding.UTF8.GetBytes(data);
        
        using (MemoryStream ms = new MemoryStream())
        {
            ms.Write(sourceBytes, 0, sourceBytes.Length);
            // 直接获取流中所有数据的字节数组
            byte[] allBytes = ms.ToArray();
            string result = Encoding.UTF8.GetString(allBytes);
            Console.WriteLine("通过ToArray获取的内容:" + result);
        }
    }
}

进阶使用场景

配合其他流完成数据转换

MemoryStream经常和其他流配合使用,比如将图片数据读取后临时存储在内存流中,再进行后续处理:

using System;
using System.IO;

class Program
{
    static void Main()
    {
        // 模拟从其他来源获取的图片字节数据
        byte[] imageSourceBytes = new byte[] { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A }; // PNG文件头示例
        
        using (MemoryStream ms = new MemoryStream())
        {
            // 将图片数据写入内存流
            ms.Write(imageSourceBytes, 0, imageSourceBytes.Length);
            // 重置流位置
            ms.Position = 0;
            // 这里可以将内存流传递给其他需要处理流的方法,比如图片处理、文件上传等
            ProcessStream(ms);
        }
    }
    
    static void ProcessStream(Stream stream)
    {
        Console.WriteLine("处理流数据,流长度:" + stream.Length);
        // 实际场景中这里会进行具体的流处理逻辑
    }
}

初始化时指定容量和初始数据

MemoryStream的构造函数支持指定初始容量和初始数据,适合已知数据规模的场景:

using System;
using System.IO;
using System.Text;

class Program
{
    static void Main()
    {
        // 指定初始容量为1024字节
        using (MemoryStream ms1 = new MemoryStream(1024))
        {
            Console.WriteLine("初始容量:" + ms1.Capacity);
        }
        
        // 指定初始数据
        byte[] initData = Encoding.UTF8.GetBytes("初始数据");
        using (MemoryStream ms2 = new MemoryStream(initData))
        {
            // 流初始位置为0,已经包含初始数据
            byte[] readBytes = new byte[ms2.Length];
            ms2.Read(readBytes, 0, readBytes.Length);
            Console.WriteLine("初始数据内容:" + Encoding.UTF8.GetString(readBytes));
        }
    }
}

使用注意事项

  • MemoryStream的数据存储在内存中,如果存储大量数据会导致内存占用过高,不适合处理超大文件
  • 使用完MemoryStream后一定要及时释放资源,推荐使用using语句自动调用Dispose方法
  • 调用GetBuffer方法时,返回的缓冲区长度可能大于实际存储的数据长度,需要结合Length属性判断有效数据范围
  • 如果需要多次读写,注意及时重置Position属性,否则会出现读取不到数据或者数据不完整的问题
  • MemoryStream不支持异步操作的传统Begin/End模式,但支持基于Task的异步方法如ReadAsync、WriteAsync

和FileStream的对比

很多开发者会混淆MemoryStream和FileStream的使用场景,两者的核心区别如下:

对比项MemoryStreamFileStream
存储位置内存缓冲区磁盘文件
操作速度
数据持久性程序结束后数据丢失数据持久化保存
适用场景临时数据处理、内存数据流转文件读写、持久化存储
资源占用占用内存占用磁盘空间,需要文件句柄

C#MemoryStream内存流操作流处理修改时间:2026-07-21 14:48:38

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。