MemorySystem筆記

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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章