【.Net实用方法总结】 整理并总结System.IO中MemoryStream类及其方法介绍
🐋作者简介:博主是一位.Net开发者,同时也是RPA和低代码平台的践行者。
🐬个人主页:会敲键盘的肘子
🐰系列专栏:.Net实用方法总结
🦀专栏简介:博主针对.Net开发和C站问答过程中遇到的问题进行总结,形成本专栏,希望可以帮助到您解决问题。
🐶座右铭:总有一天你所坚持的会反过来拥抱你。
🌈写在前面:
本文主要介绍System.IO命名空间的MemoryStream 类,介绍其常用的方法和示例说明。
👉本文关键字:System.IO、MemoryStream类、内存流、方法示例、C#
文章目录
- 1️⃣ System.IO命名空间
- 2️⃣ MemoryStream类
- ♈ 定义
- ♉ 示例
- ♉ 构造函数
- ♊ 属性
- ♌ 常用方法
- BeginRead(Byte[], Int32, Int32, AsyncCallback, Object) 开始异步读操作
- BeginWrite(Byte[], Int32, Int32, AsyncCallback, Object) 开始异步写操作
- CopyTo(Stream, Int32) 使用指定的缓冲区大小,从当前内存流中读取字节并将其写入到另一流中
- CopyToAsync(Stream, Int32, CancellationToken) 使用指定的缓冲区大小和取消令牌,从当前流中异步读取所有字节并将其写入到另一个流中
- Dispose(Boolean) 释放 [MemoryStream](https://docs.microsoft.com/zh-cn/dotnet/api/system.io.memorystream?view=net-6.0) 类使用的非托管资源,并可以选择释放托管资源
- GetBuffer() 返回从中创建此流的无符号字节的数组
- Read(Byte[], Int32, Int32) 从当前流中读取字节块并将数据写入缓冲区
- ReadAsync(Byte[], Int32, Int32,CancellationToken) 从当前流异步读取字节的序列,将流中的位置提升读取的字节数,并监视取消请求
- ReadByte() 从当前流中读取一个字节
- Write(Byte[], Int32, Int32) 使用从缓冲区读取的数据将字节块写入当前流
- WriteAsync(Byte[], Int32, Int32, CancellationToken) 将字节序列异步写入当前流,并将流的当前位置提升写入的字节数
- WriteByte(Byte) 一个字节写入文件流中的当前位置
- WriteTo(Stream) 将此内存流的整个内容写入到另一个流中
- Flush() 清除此流的缓冲区,使得所有缓冲数据都写入到文件中
- SetLength(Int64) 将当前流的长度设为指定值
- Seek(Int64, SeekOrigin) 将当前流中的位置设置为指定值
- ♎ 更多方法
1️⃣ System.IO命名空间
.NET中的IO操作命名空间,包含允许读写文件和数据流的类型以及提供基本文件和目录支持的类型。
我们在.NET中的IO操作,经常需要调用一下几个类。
- FileStream类
文件流类,负责大文件的拷贝,读写。
- Path类
Path类中方法,基本都是对字符串(文件名)的操作,与实际文件没多大关系。
-
File类
File类可以进行一些对小文件拷贝、剪切操作,还能读一些文档文件。
-
Dirctory类
目录操作,创建文件、删除目录,获取目录下文件名等等。
2️⃣ MemoryStream类
♈ 定义
创建一个流,其后备存储为内存。
public class MemoryStream : System.IO.Stream
♉ 示例
下面的代码示例演示如何使用内存作为后盾存储来读取和写入数据。
using System;
using System.IO;
using System.Text;
class MemStream
{
static void Main()
{
int count;
byte[] byteArray;
char[] charArray;
UnicodeEncoding uniEncoding = new UnicodeEncoding();
// Create the data to write to the stream.
byte[] firstString = uniEncoding.GetBytes(
"Invalid file path characters are: ");
byte[] secondString = uniEncoding.GetBytes(
Path.GetInvalidPathChars());
using(MemoryStream memStream = new MemoryStream(100))
{
// Write the first string to the stream.
memStream.Write(firstString, 0 , firstString.Length);
// Write the second string to the stream, byte by byte.
count = 0;
while(count < secondString.Length)
{
memStream.WriteByte(secondString[count++]);
}
// Write the stream properties to the console.
Console.WriteLine(
"Capacity = {0}, Length = {1}, Position = {2}\n",
memStream.Capacity.ToString(),
memStream.Length.ToString(),
memStream.Position.ToString());
// Set the position to the beginning of the stream.
memStream.Seek(0, SeekOrigin.Begin);
// Read the first 20 bytes from the stream.
byteArray = new byte[memStream.Length];
count = memStream.Read(byteArray, 0, 20);
// Read the remaining bytes, byte by byte.
while(count < memStream.Length)
{
byteArray[count++] = (byte)memStream.ReadByte();
}
// Decode the byte array into a char array
// and write it to the console.
charArray = new char[uniEncoding.GetCharCount(
byteArray, 0, count)];
uniEncoding.GetDecoder().GetChars(
byteArray, 0, count, charArray, 0);
Console.WriteLine(charArray);
}
}
}
此类型可实现 IDisposable 接口,但实际上没有任何要释放的资源。 这意味着无需通过直接调用 Dispose() 或使用语言构造(C# 中的
using
或 Visual Basic 中的Using
)对其进行处理。MemoryStream如果将对象添加到 ResX 文件或 .resources 文件,请在运行时调用GetStream该方法以检索它。
MemoryStream如果对象序列化为资源文件,则实际上将序列化为一个UnmanagedMemoryStream对象。 此行为可提供更好的性能,并能够直接获取指向数据的指针,而无需通过 Stream 方法。
♉ 构造函数
初始化 MemoryStream 类的新实例
MemoryStream()
public MemoryStream ();
CanSeek属性CanRead和CanWrite属性都设置为
true
。使用 SetLength 该方法将长度设置为大于当前流的容量的值时,当前流的容量会自动增加。
此构造函数公开返回的基础流 GetBuffer 。
MemoryStream(Byte[])
基于指定的字节数组初始化 MemoryStream 类的无法调整大小的新实例。
public MemoryStream (byte[] buffer);
参数
buffer
Byte[]
从中创建当前流的无符号字节数组。
CanSeek属性CanRead和CanWrite属性都设置为
true
。 Capacity 设置为指定字节数组的长度。 可将新流写入,但不可调整大小。流的长度不能设置为大于指定字节数组的初始长度的值;但是, (可以看到 SetLength) 截断流。
MemoryStream(Int32)
使用按指定要求初始化的可扩展容量初始化 MemoryStream 类的新实例。
public MemoryStream (int capacity);
参数
capacity
Int32
内部数组的初始大小(以字节为单位)。
示例
此代码示例是为 MemoryStream 类提供的一个更大示例的一部分。
using(MemoryStream memStream = new MemoryStream(100))
MemoryStream(Byte[], Boolean)
在 CanWrite 属性按指定设置的状态下,基于指定的字节数组初始化 MemoryStream 类的无法调整大小的新实例。
public MemoryStream (byte[] buffer, bool writable);
参数
buffer
Byte[]
内部数组的初始大小(以字节为单位)。
writable
bool
CanWrite 属性的设置,确定该流是否支持写入。
MemoryStream(Byte[], Int32, Int32)
基于字节数组的指定区域(索引)初始化 MemoryStream 类的无法调整大小的新实例。
public MemoryStream (byte[] buffer, int index, int count);
参数
buffer
Byte[]
内部数组的初始大小(以字节为单位)。
index
Int
buffer
内的索引,流从此处开始。
count
Int
流的长度(以字节为单位)。
♊ 属性
CanRead 当在派生类中重写时,获取指示当前流是否支持读取的值
public override bool CanRead { get; }
CanSeek 获取一个值,该值指示当前流是否支持查找
public override bool CanSeek { get; }
CanWrite 获取一个值,该值指示当前流是否支持写入
public override bool CanWrite { get; }
Capacity 获取或设置分配给该流的字节数
public virtual int Capacity { get; set; }
示例
// Write the stream properties to the console.
Console.WriteLine(
"Capacity = {0}, Length = {1}, Position = {2}\n",
memStream.Capacity.ToString(),
memStream.Length.ToString(),
memStream.Position.ToString());
Capacity
是系统提供的字节数组的缓冲区长度。Capacity
不能设置为小于流当前长度的值。
Length 当在派生类中重写时,获取流长度(以字节为单位)
public override long Length { get; }
♌ 常用方法
BeginRead(Byte[], Int32, Int32, AsyncCallback, Object) 开始异步读操作
public override IAsyncResult BeginRead (byte[] buffer, int offset, int count, AsyncCallback? callback, object? state);
参数
buffer
Byte[]
数据读入的缓冲区。
offset
buffer
中的字节偏移量,从该偏移量开始写入从内存流中读取的数据。
count
最多读取的字节数。
callback
[AsyncCallback](https://docs.microsoft.com/zh-cn/dotnet/api/system.int32?view=net-6.0)
可选的异步回调,在完成读取时调用。
state
Object
一个用户提供的对象,它将该特定的异步读取请求与其他请求区别开来。
返回
[IAsyncResult](https://docs.microsoft.com/zh-cn/dotnet/api/system.int32?view=net-6.0)
表示异步读取的 IAsyncResult(可能仍处于挂起状态)。
BeginWrite(Byte[], Int32, Int32, AsyncCallback, Object) 开始异步写操作
public override IAsyncResult BeginWrite (byte[] buffer, int offset, int count, AsyncCallback? callback, object? state);
参数
buffer
Byte[]
从中写入数据的缓冲区。
offset
buffer
中的字节偏移量,从此处开始写入。
count
最多写入的字节数。
callback
[AsyncCallback](https://docs.microsoft.com/zh-cn/dotnet/api/system.int32?view=net-6.0)
可选的异步回调,在完成写入时调用。
state
Object
一个用户提供的对象,它将该特定的异步写入请求与其他请求区别开来。
返回
[IAsyncResult](https://docs.microsoft.com/zh-cn/dotnet/api/system.int32?view=net-6.0)
表示异步写入的
IAsyncResult
(可能仍处于挂起状态)。
CopyTo(Stream, Int32) 使用指定的缓冲区大小,从当前内存流中读取字节并将其写入到另一流中
public override void CopyTo (System.IO.Stream destination, int bufferSize);
参数
destination
Stream
当前流的内容将复制到的流。
bufferSize
Int32
缓冲区的大小。 此值必须大于零。 默认大小为 81920。
CopyToAsync(Stream, Int32, CancellationToken) 使用指定的缓冲区大小和取消令牌,从当前流中异步读取所有字节并将其写入到另一个流中
public override System.Threading.Tasks.Task CopyToAsync (System.IO.Stream destination, int bufferSize, System.Threading.CancellationToken cancellationToken);
参数
destination
Stream
当前流的内容将复制到的流。
bufferSize
Int32
缓冲区的大小。 此值必须大于零。 默认大小为 81920。
cancellationToken
要监视取消请求的标记。
返回
表示异步复制操作的任务。
Dispose(Boolean) 释放 MemoryStream 类使用的非托管资源,并可以选择释放托管资源
protected override void Dispose (bool disposing);
GetBuffer() 返回从中创建此流的无符号字节的数组
public virtual byte[] GetBuffer ();
Read(Byte[], Int32, Int32) 从当前流中读取字节块并将数据写入缓冲区
public override int Read (byte[] buffer, int offset, int count);
参数
buffer
Byte[]
当此方法返回时,包含指定的字节数组,此数组中
offset
和 (offset
+count
- 1) 之间的值被从当前流中读取的字符所替换。
offset
buffer
中的从零开始的字节偏移量,从此处开始存储当前流中的数据。
count
最多读取的字节数。
返回
写入缓冲区中的总字节数。 如果字节数当前不可用,则总字节数可能小于所请求的字节数;如果在读取到任何字节前已到达流结尾,则为零。
示例
此代码示例是为 MemoryStream 类提供的一个更大示例的一部分。
// Read the first 20 bytes from the stream.
byteArray = new byte[memStream.Length];
count = memStream.Read(byteArray, 0, 20);
该
offset
参数提供从当前流写入到的第一个字节buffer
的偏移量。 该count
参数提供从当前流读取的最大字节数。 返回的值是读取的实际字节数,如果到达流的末尾,则为零。如果读取操作成功,则流中的当前位置会按读取的字节数向前推进。 如果发生异常,流中的当前位置保持不变。
Read
仅当到达流的末尾时,该方法才会返回零。 在所有其他情况下,Read
始终在返回之前从流中读取至少一个字节。 根据定义,如果在调用Read
时流中没有可用数据,则Read
该方法返回零, (自动) 到达流的末尾。 即使尚未到达流的末尾,实现也可以返回比请求的字节少。如果参数中指定的
buffer
字节数组是方法返回 GetBuffer 的基础缓冲区,则会覆盖数组内容,并且不会引发异常。
ReadAsync(Byte[], Int32, Int32,CancellationToken) 从当前流异步读取字节的序列,将流中的位置提升读取的字节数,并监视取消请求
public override System.Threading.Tasks.Task<int> ReadAsync (byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken);
参数
buffer
Byte[]
要写入数据的缓冲区。
offset
buffer
中的字节偏移量,从该偏移量开始写入从流中读取的数据。
count
最多读取的字节数。
cancellationToken
要监视取消请求的标记。 默认值是 None。
返回
表示异步读取操作的任务。
TResult
参数的值包含读入缓冲区的总字节数。 如果当前可用字节数少于所请求的字节数,则该结果值可小于所请求的字节数;如果已到达流结尾时,则为 0(零)。
ReadByte() 从当前流中读取一个字节
public override int ReadByte ();
返回
强制转换为 Int32 的字节;或者如果已到达流的末尾,则为 -1。
示例
此代码示例是为 MemoryStream 类提供的一个更大示例的一部分。
// Read the remaining bytes, byte by byte.
while(count < memStream.Length)
{
byteArray[count++] = (byte)memStream.ReadByte();
}
Write(Byte[], Int32, Int32) 使用从缓冲区读取的数据将字节块写入当前流
public override void Write (byte[] buffer, int offset, int count);
参数
buffer
Byte[]
字节数组。 此方法将
count
个字节从buffer
复制到当前流。
offset
buffer
中的从零开始的字节偏移量,从此处开始将字节复制到当前流。
count
要写入当前流的字节数。
示例
// Write the first string to the stream.
memStream.Write(firstString, 0 , firstString.Length);
使用 CanWrite 属性确定当前实例是否支持写入。 使用 WriteAsync 方法异步写入当前流。
如果写入操作成功,则流中的位置将按写入的字节数前进。 如果发生异常,则流中的位置保持不变。
WriteAsync(Byte[], Int32, Int32, CancellationToken) 将字节序列异步写入当前流,并将流的当前位置提升写入的字节数
public override System.Threading.Tasks.Task WriteAsync (byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken);
参数
buffer
Byte[]
从中写入数据的缓冲区。
offset
buffer
中的从零开始的字节偏移量,从此处开始将字节复制到该流。
count
最多写入的字节数。
cancellationToken
要监视取消请求的标记。 默认值是 None。
返回
表示异步写入操作的任务。
WriteByte(Byte) 一个字节写入文件流中的当前位置
public override void WriteByte (byte value);
参数
value
要写入流的字节。
示例
此代码示例是为 MemoryStream 类提供的一个更大示例的一部分。
// Write the second string to the stream, byte by byte.
count = 0;
while(count < secondString.Length)
{
memStream.WriteByte(secondString[count++]);
}
WriteTo(Stream) 将此内存流的整个内容写入到另一个流中
public virtual void WriteTo (System.IO.Stream stream);
参数
stream
要写入此内存流的流。
Flush() 清除此流的缓冲区,使得所有缓冲数据都写入到文件中
public override void Flush ();
SetLength(Int64) 将当前流的长度设为指定值
public override void SetLength (long value);
参数
value
用于设置长度的值。
如果指定的值小于流的当前长度,则会截断该流。 如果在截断流中的当前位置超过流的末尾,该方法将返回 -1,ReadByte该方法Read将零字节读取到提供的字节数组中,并且WriteWriteByte方法将指定字节追加到流末尾,增加其长度。 如果指定的值大于当前容量,并且该流可调整大小,则容量将增加,并且流中的当前位置保持不变。 如果长度增加,则旧长度和新长度之间的流内容将初始化为零。
Seek(Int64, SeekOrigin) 将当前流中的位置设置为指定值
public override long Seek (long offset, System.IO.SeekOrigin loc);
参数
offset
流内的新位置。 它是相对于
loc
参数的位置,而且可正可负。
loc
类型 SeekOrigin 的值,它用作查找引用点。
返回
流内的新位置,通过将初始引用点和偏移量合并计算而得。
示例
// Set the position to the beginning of the stream.
memStream.Seek(0, SeekOrigin.Begin);
支持查找超出流长度的任何位置。
如果不使用 Seek 该方法来确定流中的新位置(如果使用 MemoryStream 非零偏移量初始化)。 如果这样做, Seek 将返回不准确的值。 请改用该 Position 属性获取流的新位置。
♎ 更多方法
更多方法请查阅官方文档MemoryStream类。
⭐写在结尾:
文章中出现的任何错误请大家批评指出,一定及时修改。
希望写在这里的小伙伴能给个三连支持!
相关文章
- [置顶]这些.NET开源项目你知道吗?.NET平台开源文档与报表处理组件集合(三)
- 使用 Visual Studio 部署 .NET Core 应用 ——.Net Core 部署到Ubuntu 16.04
- .NET常用的扩展方法整理
- .Net魔法堂:史上最全的ActiveX开发教程——发布篇
- dojo从asp.net中获取json数据
- ASP.NET利用JQuery实现AJAX(前台脚本代码)调用后台静态方法
- Asp.Net Web API 2第十七课——Creating an OData Endpoint in ASP.NET Web API 2(OData终结点)
- asp.net select Case条件语句的使用方法
- asp.net中导出excel数据的方法汇总
- 【类库】私房干货.Net数据层方法的封装
- 基于LumiSoft.Net.dll发、收、删邮件
- jQuery跨域请求,跨域Post提交数据的方法(.net/SQL技术交流群206656202 入群需注明博客园) - 思...
- ASP.NET Core 6框架揭秘实例演示[13]:日志的基本编程模式
- ASP.NET Core 6框架揭秘实例演示[05]:依赖注入基本编程模式
- 如何让ASP.NET Web API的Action方法在希望的Culture下执行
- Atitit ..Net Framework sdk 3.0 3.5 4.04.5 4.6 4.7 .net core版本新特性 v2 s22 1. 新特性来源于 down ms 官方网站1
- Atitit.提升软件Web应用程序 app性能的方法原理 h5 js java c# php python android .net
- .NET MVC访问某方法后会跳转页面
- ASP.NET MVC上传图片前后台内容
- 【.Net实用方法总结】 整理并总结System.Data中DataColumnCollection类及其方法介绍
- 【.Net实用方法总结】 整理并总结System.IO中BufferedStream类及其方法介绍
- 【.Net实用方法总结】 整理并总结System.IO中StringReader类及其方法介绍
- 猿创征文|【.Net实用方法总结】 整理并总结System.IO中FileStream类及其方法介绍
- 【.Net实用方法总结】 整理并总结System.IO中FileInfo类及其方法介绍
- 【.Net实用方法总结】 整理并总结System.IO中File类及其方法介绍