属性,函数见https://docs.microsoft.com/zh-cn/dotnet/api/system.io.memorystream?view=net-5.0
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
namespace MemorySystemDemo
{
class Program
{
static void Main(string[] args)
{
MemoryStream ms1 = new MemoryStream();//不传入需要分配的字节数,默认为0,即初始分配字节数长度为0
byte[] bytesArr1 = Encoding.UTF8.GetBytes("还是用中文,测试吧");
Console.WriteLine("写入前");
Console.WriteLine(ms1.Position);//0 当前的位置
Console.WriteLine(ms1.Capacity);//0 分配给该流的字节数,创建空流时,分配0字节数
Console.WriteLine(ms1.Length);//0 流内的内容实际占用的字节数
ms1.Write(bytesArr1, 0, bytesArr1.Length);
Console.WriteLine("写入后");
Console.WriteLine(ms1.Position);//27 写入内容后,位置指针后移到 写入位置 + 写入字节长度
Console.WriteLine(ms1.Capacity);//256 写入内容,系统根据写入内容自动分配合适的字节数,最小为256,之后按字节数递增257,258,259...若写入的内容小于初始时定义的字节数,该流分配的字节数不会减少,多余的自动补0,反之会自动扩充
Console.WriteLine(ms1.Length);//27 内容实际占用字节数
Console.WriteLine(getString(ms1.ToArray()));//还是用中文,测试吧
DrawLine();
Console.WriteLine("position设置位置,写入单个字节");
ms1.Position = 1;//设置流当前位置
byte b1 = (byte)'1';
ms1.WriteByte(b1);//写入单个字节
Console.WriteLine(ms1.Position);//2 写入内容后,位置指针后移到 写入位置 + 写入字节长度
Console.WriteLine(ms1.Capacity);//256
Console.WriteLine(ms1.Length);//27 内容实际占用字节数
Console.WriteLine(getString(ms1.ToArray()));//?1 ? 是用中文,测试吧 一个汉字占用一个三个字节,前三个字节组成汉字“还”,将1位置字节修改后,合成不了汉字,导致出现“?”
DrawLine();
Console.WriteLine("seek设置位置,写入单个字节");
long pos1 = ms1.Seek(1, SeekOrigin.Begin);//流内的新位置。 它是相对于 loc 参数(SeekOrigin)的位置,而且可正可负。
byte b2 = (byte)191;//汉字"还" 由232,191,152组成,将上面‘1’替换的191替换回去,句子又重新组成
ms1.WriteByte(b2);//写入单个字节
Console.WriteLine(ms1.Position);//2 写入内容后,位置指针后移到 写入位置 + 写入字节长度
Console.WriteLine(ms1.Capacity);//256
Console.WriteLine(ms1.Length);//27 内容实际占用字节数
Console.WriteLine(getString(ms1.ToArray()));//还是用中文,测试吧
DrawLine();
Console.WriteLine("读取当前位置字节");
byte b3 = (byte)ms1.ReadByte();
Console.WriteLine(b3);//152 上面写入之后,当前位置为2,读取到152
DrawLine();
Console.WriteLine("读取对应字节段");
//public override int Read(byte[] buffer,int offset,int count)
//重点参数含义offset: buffer 中的从零开始的字节偏移量,从此处开始存储从当前流中的数据。
byte[] readByteArr1 = new byte[10];
ms1.Read(readByteArr1, 0, readByteArr1.Length);
Console.WriteLine(getString(readByteArr1));//是用中? 由于上面读取了字节,所以当前位置后移一位,变成了3,开始从第3位读取字节段,问号原因同上
ms1.Position = 0;//重置
byte[] readByteArr2 = new byte[10];
ms1.Read(readByteArr2, 0, readByteArr2.Length);
Console.WriteLine(getString(readByteArr2));//还是用?
ms1.Position = 0;//重置
byte[] readByteArr3 = new byte[9];
ms1.Read(readByteArr3, 0, readByteArr3.Length);
Console.WriteLine(getString(readByteArr3));//还是用
ms1.Position = ms1.Length;//重置
byte[] readByteArr4 = new byte[9];
ms1.Read(readByteArr4, 0, readByteArr4.Length);//
Console.WriteLine(getString(readByteArr4));// 由于读取时,指针已在流尾端,所以读取不到字节
ms1.Position = 0;//重置
byte[] readByteArr5 = new byte[9];
//ms1.Read(readByteArr5, 2, readByteArr5.Length);//exception 数组越界,offest为数组偏移,这里读取字节数为9,写入位置为readByteArr5索引为2的位置,即可写入长度为7,故数组越界
//Console.WriteLine(getString(readByteArr5));//
DrawLine();
Console.WriteLine("对象与字节数组的转换,序列化写入内存流与反序列化从内存流读出");
MemoryStream ms2 = new MemoryStream();
Student student = new Student();
student.name = "小明";
student.age = 18;
student.sex = true;
IFormatter formatter = new BinaryFormatter();
formatter.Serialize(ms2, student);
Console.WriteLine(ms2.Position);//168
Console.WriteLine(ms2.Capacity);//256
Console.WriteLine(ms2.Length);//168
MemoryStream ms3 = new MemoryStream(ms2.ToArray());
IFormatter formatter2 = new BinaryFormatter();
Student student2 = (Student)formatter2.Deserialize(ms3);
Console.WriteLine(student2);//name:小明,age:18,sex:True
Console.ReadKey();
}
static string getString(byte[] arr)
{
return Encoding.UTF8.GetString(arr);
}
static void DrawLine()
{
Console.WriteLine("-----------------------------------------");
}
}
[Serializable]
public class Student
{
public string name;
public int age;
public bool sex;
public override string ToString()
{
return $"name:{name},age:{age},sex:{sex}";
}
}
}