C# MemoryStream
最后修改于 2025 年 4 月 20 日
本教程介绍如何在 C# 中使用 MemoryStream 类进行内存流操作。MemoryStream 提供了一个流接口,用于处理内存中的数据。
MemoryStream 类创建一个使用内存作为存储的流,而不是磁盘或网络连接。它继承自 Stream 类。
当您需要流功能但又想避免磁盘 I/O 时,MemoryStream 非常有用。它通常用于临时存储、数据操作以及作为中间缓冲区。
MemoryStream 基础示例
此示例演示了创建 MemoryStream 并向其写入一些字节。 然后,我们从流中读回数据。
using System;
using System.IO;
using System.Text;
class Program
{
static void Main()
{
// Create a MemoryStream
using (MemoryStream stream = new MemoryStream())
{
// Write data to the stream
byte[] data = Encoding.UTF8.GetBytes("Hello MemoryStream!");
stream.Write(data, 0, data.Length);
// Reset position to read from beginning
stream.Position = 0;
// Read data back
byte[] buffer = new byte[stream.Length];
stream.Read(buffer, 0, buffer.Length);
string text = Encoding.UTF8.GetString(buffer);
Console.WriteLine(text);
}
}
}
该示例创建了一个 MemoryStream,将一个字符串作为字节写入,然后将其读回。 在读取之前,Position 属性将重置为 0,以便从头开始。
MemoryStream 实现了 IDisposable,因此我们在 using 语句中使用它。 写入数据时,流会自动扩展。 该示例显示了 MemoryStream 操作中常见的基本写入-读取循环。
读取和写入基本类型
MemoryStream 可以与 BinaryWriter 和 BinaryReader 一起使用来处理基本数据类型。 此示例演示如何写入和读取不同的类型。
using System;
using System.IO;
class Program
{
static void Main()
{
using (MemoryStream stream = new MemoryStream())
{
// Write data using BinaryWriter
using (BinaryWriter writer = new BinaryWriter(stream, Encoding.UTF8, true))
{
writer.Write(42);
writer.Write(3.14159);
writer.Write(true);
writer.Write("C# MemoryStream");
}
// Reset position to read
stream.Position = 0;
// Read data using BinaryReader
using (BinaryReader reader = new BinaryReader(stream, Encoding.UTF8, true))
{
Console.WriteLine(reader.ReadInt32());
Console.WriteLine(reader.ReadDouble());
Console.WriteLine(reader.ReadBoolean());
Console.WriteLine(reader.ReadString());
}
}
}
}
BinaryWriter 和 BinaryReader 为基本类型提供了便捷的方法。 流被传递给它们的构造函数,保持流打开以供进一步使用。
请注意 BinaryWriter/BinaryReader 构造函数中的 true 参数。 这会在写入器/读取器被释放后保持流打开。 数据按顺序写入,并且必须按相同的顺序读取。
将 MemoryStream 转换为字节数组
MemoryStream 可以轻松地将其内容转换为字节数组。 此示例演示如何从 MemoryStream 获取底层字节数组。
using System;
using System.IO;
using System.Text;
class Program
{
static void Main()
{
// Create and write to MemoryStream
using (MemoryStream stream = new MemoryStream())
{
string text = "This will be converted to a byte array";
byte[] data = Encoding.UTF8.GetBytes(text);
stream.Write(data, 0, data.Length);
// Get the byte array
byte[] byteArray = stream.ToArray();
Console.WriteLine($"Byte array length: {byteArray.Length}");
Console.WriteLine($"Content: {Encoding.UTF8.GetString(byteArray)}");
}
}
}
ToArray 方法创建一个包含流数据的新字节数组。 当您需要将数据传递给期望字节数组的方法时,这非常有用。
该示例将一个字符串写入流,然后将其转换为字节数组。 原始流保持不变。 此操作非常有效,因为它直接访问内部缓冲区。
将 MemoryStream 与 StreamWriter/Reader 一起使用
MemoryStream 可以与面向文本的 StreamWriter 和 StreamReader 类一起使用。 此示例演示了基于文本的操作。
using System;
using System.IO;
using System.Text;
class Program
{
static void Main()
{
using (MemoryStream stream = new MemoryStream())
{
// Write text using StreamWriter
using (StreamWriter writer = new StreamWriter(stream, Encoding.UTF8, 1024, true))
{
writer.WriteLine("First line of text");
writer.WriteLine("Second line of text");
writer.Flush();
// Reset position to read
stream.Position = 0;
// Read text using StreamReader
using (StreamReader reader = new StreamReader(stream, Encoding.UTF8, false, 1024, true))
{
string line;
while ((line = reader.ReadLine()) != null)
{
Console.WriteLine(line);
}
}
}
}
}
}
StreamWriter 和 StreamReader 处理文本编码并提供基于行的操作。 Flush 调用确保所有缓冲数据都写入流。
该示例演示了如何链接流操作。 leaveOpen 参数设置为 true,以在写入器被释放后保持 MemoryStream 可用。 这种模式在使用分层流操作时很常见。
具有初始容量的 MemoryStream
可以使用特定容量初始化 MemoryStream 以优化性能。 此示例演示如何使用容量构造函数。
using System;
using System.IO;
class Program
{
static void Main()
{
// Create with initial capacity of 1KB
using (MemoryStream stream = new MemoryStream(1024))
{
Console.WriteLine($"Initial capacity: {stream.Capacity}");
// Write data until we exceed capacity
byte[] data = new byte[512];
for (int i = 0; i < 5; i++)
{
stream.Write(data, 0, data.Length);
Console.WriteLine($"Capacity after write {i+1}: {stream.Capacity}");
}
}
}
}
设置初始容量可以防止不必要的重新分配。 流将在需要时自动扩展,但这会带来性能开销。
该示例显示了容量如何随着数据的写入而增长。 初始容量为 1024 字节。 写入 2.5KB 数据后,容量已加倍以适应新数据。 这演示了自动调整大小的行为。
MemoryStream 作为网络操作的缓冲区
MemoryStream 通常用作网络操作的缓冲区。 此示例模拟接收数据块并在 MemoryStream 中组装它们。
using System;
using System.IO;
using System.Text;
class Program
{
static void Main()
{
// Simulate receiving data chunks
byte[][] chunks = {
Encoding.UTF8.GetBytes("This is "),
Encoding.UTF8.GetBytes("a multi-chunk "),
Encoding.UTF8.GetBytes("message assembled "),
Encoding.UTF8.GetBytes("in MemoryStream")
};
using (MemoryStream stream = new MemoryStream())
{
// Process each chunk
foreach (byte[] chunk in chunks)
{
Console.WriteLine($"Processing {chunk.Length} byte chunk");
stream.Write(chunk, 0, chunk.Length);
}
// Get complete message
stream.Position = 0;
using (StreamReader reader = new StreamReader(stream))
{
Console.WriteLine("Complete message:");
Console.WriteLine(reader.ReadToEnd());
}
}
}
}
MemoryStream 非常适合从多个来源组装数据。 它提供了在数据到达时写入数据并在完成后读取数据的灵活性。
该示例模拟通过网络以块的形式接收数据。 每个块在到达时都会写入 MemoryStream。 最后,从流中读取完整消息。 这种模式在网络编程中很常见。
MemoryStream 用于图像处理
MemoryStream 通常用于图像处理。 此示例演示如何将图像加载到 MemoryStream 中,然后将其保存到文件。
using System;
using System.IO;
using System.Drawing;
class Program
{
static void Main()
{
// Load an image file into MemoryStream
byte[] imageBytes = File.ReadAllBytes("input.jpg");
using (MemoryStream stream = new MemoryStream(imageBytes))
{
// Process the image in memory
using (Image image = Image.FromStream(stream))
{
Console.WriteLine($"Image size: {image.Width}x{image.Height}");
// Save to a new file (simulating processing)
image.Save("output.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
}
}
Console.WriteLine("Image processed and saved");
}
}
MemoryStream 允许图像处理,而无需多次磁盘操作。 图像一次加载到内存中,并且可以高效地处理。
该示例将图像文件读取到字节数组中,然后从中创建一个 MemoryStream。 Image 类可以直接从流中加载。 当处理来自数据库或网络源的图像时,此方法非常有用。
来源
本教程介绍了如何在 C# 中使用 MemoryStream 处理各种场景,包括基本操作、基本类型、文本处理、缓冲和图像处理。
作者
列出所有 C# 教程。