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}";
        }
    }
}

 

你可能感兴趣的:(原创,c#,MemorySystem)