屬性,函數見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}";
}
}
}