独立项目-MemoryStream-内存数据读写-01

Posted Dean二十七

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了独立项目-MemoryStream-内存数据读写-01相关的知识,希望对你有一定的参考价值。

学习内容:

  1.内存读写原理,字节的转换。

  2.编写自己的内存读写类,这个类是项目中比较核心的类。

    注:电脑中最基本的单位是“位”(bit),但是“位”(bit)这个单位太小,所以字节(Byte)是电脑存储容量的基本计量单位。Byte可简写成位B,一个字节由8个二进制位组成,其最小值位0,最大值为11111111,一个存储单元能存储一个字节的内容。

 

  一、int转换为byte 与 byte转换为int示例:

#region 模块信息
// **********************************************************************
// Copyright (C) 2018 The company name
//
// 文件名(File Name):             Test_MMOMemory.cs
// 作者(Author):                  Dean1874
// 创建时间(CreateTime):          2018-04-04 18:19:14
// 修改者列表(modifier):
// 模块描述(Module description):
// 
// **********************************************************************
#endregion

using System;
using UnityEngine;

public class Test_MMOMemory : MonoBehaviour 
{
    private void Start()
    {
        IntToByte();
        ByteToInt();
    }

    /// <summary>
    /// 把int转换成byte数据
    /// </summary>
    private void IntToByte()
    {//int 4个字节(4个byte)
        int a = 10;

        //把int转换成byte数据
        byte[] array1 = BitConverter.GetBytes(a);

        //提示:循环尽量用for,少用foreach
        for (int i = 0; i < array1.Length; ++i)
        {
            Debug.Log(string.Format("array1{0} = {1}", i, array1[i]));
        }

        //int 4个字节(4个byte)
        int b = 98;

        //把int转换成byte数据
        byte[] array2 = BitConverter.GetBytes(b);

        //提示:循环尽量用for,少用foreach
        for (int i = 0; i < array2.Length; ++i)
        {
            Debug.Log(string.Format("array2{0} = {1}", i, array2[i]));
        }

        //int 4个字节(4个byte)
        int c = 8998;

        //把int转换成byte数据
        byte[] array3 = BitConverter.GetBytes(c);

        //提示:循环尽量用for,少用foreach
        for (int i = 0; i < array3.Length; ++i)
        {
            Debug.Log(string.Format("array3{0} = {1}", i, array3[i]));
        }
    }

    private void ByteToInt()
    {
        byte[] array = new byte[4];
        array[0] = 86;
        array[1] = 128;
        array[2] = 224;
        array[3] = 5;

        int a = BitConverter.ToInt32(array, 0);
        Debug.Log(string.Format("a = {0}", a));
    }
}

 

  二、如何写自己的MMO_MemoryStream脚本:

#region 模块信息
// **********************************************************************
// Copyright (C) 2018 The company name
//
// 文件名(File Name):             MMO_MemoryStream.cs
// 作者(Author):                  Dean1874
// 创建时间(CreateTime):          2018-04-04 18:39:06
// 修改者列表(modifier):
// 模块描述(Module description):
// 
// **********************************************************************
#endregion

using System;
using System.IO;
using System.Text;
using UnityEngine;

/// <summary>
/// 数据转换(byte、short、int、long、float、decimal、bool、string)
/// </summary>
public class MMO_MemoryStream : MemoryStream 
{
    /// <summary>
    /// 构造函数 传递给基类
    /// </summary>
    /// <param name="buffer"></param>
    public MMO_MemoryStream(byte[] buffer):base(buffer)
    {
    }

    /// <summary>
    /// 构造函数
    /// </summary>
    public MMO_MemoryStream() : base()
    {

    }

    #region short相关

    /// <summary>
    /// 从流中读取一个short数据
    /// </summary>
    /// <returns></returns>
    public short ReadShort()
    {
        byte[] array = new byte[2];
        base.Read(array, 0, 2);

        return BitConverter.ToInt16(array, 0);
    }

    /// <summary>
    /// 把一个short数据写入流
    /// </summary>
    /// <param name="_value"></param>
    public void WriteShort(short _value)
    {
        byte[] array = BitConverter.GetBytes(_value);
        base.Write(array, 0, array.Length);
    }

    #endregion

    #region ushort相关

    /// <summary>
    /// 从流中读取一个ushort数据
    /// </summary>
    /// <returns></returns>
    public ushort ReadUShort()
    {
        byte[] array = new byte[2];
        base.Read(array, 0, 2);

        return BitConverter.ToUInt16(array, 0);
    }

    /// <summary>
    /// 把一个ushort数据写入流
    /// </summary>
    /// <param name="_value"></param>
    public void WriteUShort(ushort _value)
    {
        byte[] array = BitConverter.GetBytes(_value);
        base.Write(array, 0, array.Length);
    }

    #endregion

    #region int相关

    /// <summary>
    /// 从流中读取一个int数据
    /// </summary>
    /// <returns></returns>
    public int ReadInt()
    {
        byte[] array = new byte[4];
        base.Read(array, 0, 4);

        return BitConverter.ToInt32(array, 0);
    }

    /// <summary>
    /// 把一个int数据写入流
    /// </summary>
    /// <param name="_value"></param>
    public void WriteInt(int _value)
    {
        byte[] array = BitConverter.GetBytes(_value);
        base.Write(array, 0, array.Length);
    }

    #endregion

    #region uint相关

    /// <summary>
    /// 从流中读取一个uint数据
    /// </summary>
    /// <returns></returns>
    public uint ReadUInt()
    {
        byte[] array = new byte[4];
        base.Read(array, 0, 4);

        return BitConverter.ToUInt32(array, 0);
    }

    /// <summary>
    /// 把一个uint数据写入流
    /// </summary>
    /// <param name="_value"></param>
    public void WriteUInt(uint _value)
    {
        byte[] array = BitConverter.GetBytes(_value);
        base.Write(array, 0, array.Length);
    }

    #endregion

    #region long相关

    /// <summary>
    /// 从流中读取一个long数据
    /// </summary>
    /// <returns></returns>
    public long ReadLong()
    {
        byte[] array = new byte[8];
        base.Read(array, 0, 8);

        return BitConverter.ToInt64(array, 0);
    }

    /// <summary>
    /// 把一个long数据写入流
    /// </summary>
    /// <param name="_value"></param>
    public void WriteLong(long _value)
    {
        byte[] array = BitConverter.GetBytes(_value);
        base.Write(array, 0, array.Length);
    }

    #endregion

    #region ulong相关

    /// <summary>
    /// 从流中读取一个ulong数据
    /// </summary>
    /// <returns></returns>
    public ulong ReadULong()
    {
        byte[] array = new byte[8];
        base.Read(array, 0, 8);

        return BitConverter.ToUInt64(array, 0);
    }

    /// <summary>
    /// 把一个ulong数据写入流
    /// </summary>
    /// <param name="_value"></param>
    public void WriteULong(ulong _value)
    {
        byte[] array = BitConverter.GetBytes(_value);
        base.Write(array, 0, array.Length);
    }

    #endregion

    #region float相关

    /// <summary>
    /// 从流中读取一个float数据
    /// </summary>
    /// <returns></returns>
    public float ReadFloat()
    {
        byte[] array = new byte[4];
        base.Read(array, 0, 4);

        return BitConverter.ToSingle(array, 0);
    }

    /// <summary>
    /// 把一个float数据写入流
    /// </summary>
    /// <param name="_value"></param>
    public void WriteFloat(float _value)
    {
        byte[] array = BitConverter.GetBytes(_value);
        base.Write(array, 0, array.Length);
    }

    #endregion

    #region double相关

    /// <summary>
    /// 从流中读取一个double数据
    /// </summary>
    /// <returns></returns>
    public double ReadDouble()
    {
        byte[] array = new byte[8];
        base.Read(array, 0, 8);

        return BitConverter.ToDouble(array, 0);
    }

    /// <summary>
    /// 把一个double数据写入流
    /// </summary>
    /// <param name="_value"></param>
    public void WriteDouble (double _value)
    {
        byte[] array = BitConverter.GetBytes(_value);
        base.Write(array, 0, array.Length);
    }

    #endregion

    #region bool相关

    /// <summary>
    /// 从流中读取一个bool数据
    /// </summary>
    /// <returns></returns>
    public bool ReadBool()
    {
        return base.ReadByte() == 1;
    }

    /// <summary>
    /// 把一个bool数据写入流
    /// </summary>
    /// <param name="_value"></param>
    public void WriteBool(bool _value)
    {
        base.WriteByte((byte)(_value == true ? 1 : 0));
    }

    #endregion

    #region UTF8String相关
    /// <summary>
    /// 从流中读取一个string数据
    /// </summary>
    /// <returns></returns>
    public string ReadUTF8String()
    {
        ushort len = ReadUShort();
        byte[] array = new byte[len];
        base.Read(array, 0, len);

        return Encoding.UTF8.GetString(array);
    }

    /// <summary>
    /// 把一个string数据写入流
    /// </summary>
    /// <param name="_value"></param>
    public void WriteUTF8String(string _value)
    {
        byte[] array = Encoding.UTF8.GetBytes(_value);

        if (array.Length > 65535)
        {
            throw new InvalidCastException("字符串超出范围");
        }

        //先写入字符串的长度
        WriteUShort((ushort)array.Length);

        //再将字符串写入
        base.Write(array, 0, array.Length);
    }
    #endregion
}

 

  三、在 Test_MMOMemory.cs 脚本中测试 MMO_MemoryStream.cs 脚本

#region 模块信息
// **********************************************************************
// Copyright (C) 2018 The company name
//
// 文件名(File Name):             Test_MMOMemory.cs
// 作者(Author):                  Dean1874
// 创建时间(CreateTime):          2018-04-04 18:19:14
// 修改者列表(modifier):
// 模块描述(Module description):
// 
// **********************************************************************
#endregion

using System;
using UnityEngine;

public class Item
{
    public int ID;
    public string Name;
}

public class Test_MMOMemory : MonoBehaviour 
{
    private void Start()
    {
        Item item = new Item() { ID = 1874, Name = "Dean1993"};

        byte[] array = null;

        //using自动释放
        using (MMO_MemoryStream ms = new MMO_MemoryStream())
        {
            //写入流
            ms.WriteInt(item.ID);
            ms.WriteUTF8String(item.Name);

            array = ms.ToArray();
        }

        if (array != null)
        {
            for (int i = 0; i < array.Length; ++i)
            {
                Debug.Log(string.Format("{0} = {1}", i, array[i]));
            }
        }

        Item item2 = new Item();
        using (MMO_MemoryStream ms = new MMO_MemoryStream(array))
        {
            item2.ID = ms.ReadInt();
            item2.Name = ms.ReadUTF8String();
        }

        Debug.Log(string.Format("item2 ID = {0}", item2.ID));
        Debug.Log(string.Format("item2 Name = {0}", item2.Name));
    }

    /// <summary>
    /// 把int转换成byte数据
    /// </summary>
    private void IntToByte()
    {//int 4个字节(4个byte)
        int a = 10;

        //把int转换成byte数据
        byte[] array1 = BitConverter.GetBytes(a);

        //提示:循环尽量用for,少用foreach
        for (int i = 0; i < array1.Length; ++i)
        {
            Debug.Log(string.Format("array1{0} = {1}", i, array1[i]));
        }

        //int 4个字节(4个byte)
        int b = 98;

        //把int转换成byte数据
        byte[] array2 = BitConverter.GetBytes(b);

        //提示:循环尽量用for,少用foreach
        for (int i = 0; i < array2.Length; ++i)
        {
            Debug.Log(string.Format("array2{0} = {1}", i, array2[i]));
        }

        //int 4个字节(4个byte)
        int c = 8998;

        //把int转换成byte数据
        byte[] array3 = BitConverter.GetBytes(c);

        //提示:循环尽量用for,少用foreach
        for (int i = 0; i < array3.Length; ++i)
        {
            Debug.Log(string.Format("array3{0} = {1}", i, array3[i]));
        }
    }

    private void ByteToInt()
    {
        byte[] array = new byte[4];
        array[0] = 86;
        array[1] = 128;
        array[2] = 224;
        array[3] = 5;

        int a = BitConverter.ToInt32(array, 0);
        Debug.Log(string.Format("a = {0}", a));
    }
}

 

以上是关于独立项目-MemoryStream-内存数据读写-01的主要内容,如果未能解决你的问题,请参考以下文章

MemoryStream相关知识分享

c# 在内存打包zip 多个文件 上传服务器 MemoryStream ZipArchiveMode

JSON string 在内存中转流 MemoryStream 代码,以及需要注意的问题utf-8问题

将指针转换为 MemoryStream?

无法写入新的 MemoryStream - 流已关闭

来自 HttpContent 的 MemoryStream 无需复制