UNITY数据储存—2进制相关

本文详细介绍了C#中数据类型之间的转换,如BitConverter用于不同类型到字节的转换,以及Encoding处理字符串编码和解码。此外,还涵盖了文件操作(如FileStream、File、Directory和编码转换)、2进制序列化与反序列化以及常用的加密算法应用。
摘要由CSDN通过智能技术生成

各类型数据和字节数据相互转换

除string类型其余类型转化

        //C#提供了一个公共类帮助我们进行转化
        //我们只需要记住API即可
        //类名:BitConverter
        //命名空间:using System

        //1.将各类型转字节
        byte[] bytes = BitConverter.GetBytes(256);

        //2.字节数组转各类型
        int i = BitConverter.ToInt32(bytes, 0);
        print(i);

string类型

        //编码是用预先规定的方法将文字、数字或其它对象编成数码,或将信息、数据转换成规定的电脉冲信号。
        //为保证编码的正确性,编码要规范化、标准化,即需有标准的编码格式。
        //常见的编码格式有ASCII、ANSI、GBK、GB2312、UTF - 8、GB18030和UNICODE等。

        // 说人话
        // 计算机中数据的本质就是2进制数据
        // 编码格式就是用对应的2进制数 对应不同的文字
        // 由于世界上有各种不同的语言,所有会有很多种不同的编码格式
        // 不同的编码格式 对应的规则是不同的

        // 如果在读取字符时采用了不统一的编码格式,可能会出现乱码

        // 游戏开发中常用编码格式 UTF-8
        // 中文相关编码格式 GBK
        // 英文相关编码格式 ASCII

        // 在C#中有一个专门的编码格式类 来帮助我们将字符串和字节数组进行转换

        // 类名:Encoding
        // 需要引用命名空间:using System.Text;

        //1.将字符串以指定编码格式转字节
        byte[] bytes2 = Encoding.UTF8.GetBytes("唐老狮");

        //2.字节数组以指定编码格式转字符串
        string s = Encoding.UTF8.GetString(bytes2);
        print(s);

文件相关操作公共类

         //C#提供了一个名为File(文件)的公共类 
        //让我们可以快捷的通过代码操作文件相关
        //类名:File
        //命名空间: System.IO

文件操作File类的常用内容

        //1.判断文件是否存在
        if(File.Exists(Application.dataPath + "/UnityTeach.tang"))
        {
            print("文件存在");
        }
        else
        {
            print("文件不存在");
        }

        //2.创建文件
        //FileStream fs = File.Create(Application.dataPath + "/UnityTeach.tang");

        //3.写入文件
        //将指定字节数组 写入到指定路径的文件中
        byte[] bytes = BitConverter.GetBytes(999);
        File.WriteAllBytes(Application.dataPath + "/UnityTeach.tang", bytes);
        //将指定的string数组内容 一行行写入到指定路径中
        string[] strs = new string[] { "123", "唐老狮", "123123kdjfsalk", "123123123125243"};
        File.WriteAllLines(Application.dataPath + "/UnityTeach2.tang", strs);
        //将指定字符串写入指定路径
        File.WriteAllText(Application.dataPath + "/UnityTeach3.tang", "唐老狮哈\n哈哈哈哈123123131231241234123");

        //4.读取文件
        //读取字节数据
        bytes = File.ReadAllBytes(Application.dataPath + "/UnityTeach.tang");
        print(BitConverter.ToInt32(bytes, 0));

        //读取所有行信息
        strs = File.ReadAllLines(Application.dataPath + "/UnityTeach2.tang");
        for (int i = 0; i < strs.Length; i++)
        {
            print(strs[i]);
        }

        //读取所有文本信息
        print(File.ReadAllText(Application.dataPath + "/UnityTeach3.tang"));

        //5.删除文件
        //注意 如果删除打开着的文件 会报错
        File.Delete(Application.dataPath + "/UnityTeach.tang");

        //6.复制文件
        //参数一:现有文件 需要是流关闭状态
        //参数二:目标文件
        File.Copy(Application.dataPath + "/UnityTeach2.tang", Application.dataPath + "/唐老狮.tanglaoshi", true);

        //7.文件替换
        //参数一:用来替换的路径
        //参数二:被替换的路径
        //参数三:备份路径
        File.Replace(Application.dataPath + "/UnityTeach3.tang", Application.dataPath + "/唐老狮.tanglaoshi", Application.dataPath + "/唐老狮备份.tanglaoshi");

        //8.以流的形式 打开文件并写入或读取
        //参数一:路径
        //参数二:打开模式
        //参数三:访问模式
        //FileStream fs = File.Open(Application.dataPath + "/UnityTeach2.tang", FileMode.OpenOrCreate, FileAccess.ReadWrite);

文件流

        //在C#中提供了一个文件流类 FileStream类
        //它主要作用是用于读写文件的细节
        //FileStream可以以读写字节的形式处理文件 

        //类名:FileStream
        //需要引用命名空间:System.IO 

FileStream文件流类常用方法

打开或创建指定文件

        //方法一:new FileStream
        //参数一:路径
        //参数二:打开模式
        //  CreateNew:创建新文件 如果文件存在 则报错
        //  Create:创建文件,如果文件存在 则覆盖
        //  Open:打开文件,如果文件不存在 报错
        //  OpenOrCreate:打开或者创建文件根据实际情况操作
        //  Append:若存在文件,则打开并查找文件尾,或者创建一个新文件
        //  Truncate:打开并清空文件内容
        //参数三:访问模式
        //参数四:共享权限
        //  None 谢绝共享
        //  Read 允许别的程序读取当前文件
        //  Write 允许别的程序写入该文件
        //  ReadWrite 允许别的程序读写该文件
        //FileStream fs = new FileStream(Application.dataPath + "/Lesson3.tang", FileMode.Create, FileAccess.ReadWrite);

        //方法二:File.Create
        //参数一:路径
        //参数二:缓存大小
        //参数三:描述如何创建或覆盖该文件(不常用)
        //  Asynchronous 可用于异步读写
        //  DeleteOnClose 不在使用时,自动删除
        //  Encrypted 加密
        //  None 不应用其它选项
        //  RandomAccess 随机访问文件
        //  SequentialScan 从头到尾顺序访问文件
        //  WriteThrough 通过中间缓存直接写入磁盘
        //FileStream fs2 = File.Create(Application.dataPath + "/Lesson3.tang");

        //方法三:File.Open
        //参数一:路径
        //参数二:打开模式
        //FileStream fs3 = File.Open(Application.dataPath + "/Lesson3.tang", FileMode.Open);

 重要属性和方法

 

        //FileStream fs = File.Open(Application.dataPath + "Lesson3.tang", FileMode.OpenOrCreate);
        //文本字节长度
        //print(fs.Length);

        //是否可写
        //if( fs.CanRead )
        //{

        //}

        //是否可读
        //if( fs.CanWrite )
        //{

        //}

        //将字节写入文件 当写入后 一定执行一次
        //fs.Flush();

        //关闭流 当文件读写完毕后 一定执行
        //fs.Close();

        //缓存资源销毁回收
        //fs.Dispose();

 写入字节

 字符串写入时需要字符串的长度信息,所以一般都会在用其他变量记录长度

print(Application.persistentDataPath);
        using (FileStream fs = new FileStream(Application.persistentDataPath + "/Lesson3.tang", FileMode.OpenOrCreate, FileAccess.Write))
        {

            byte[] bytes = BitConverter.GetBytes(999);
            //方法:Write
            //参数一:写入的字节数组
            //参数二:数组中的开始索引
            //参数三:写入多少个字节
            fs.Write(bytes, 0, bytes.Length);

            //写入字符串时
            bytes = Encoding.UTF8.GetBytes("唐老狮哈哈哈哈");
            //先写入长度
            //int length = bytes.Length;
            fs.Write(BitConverter.GetBytes(bytes.Length), 0, 4);
            //再写入字符串具体内容
            fs.Write(bytes, 0, bytes.Length);

            //避免数据丢失 一定写入后要执行的方法
            fs.Flush();
            //销毁缓存 释放资源
            fs.Dispose();
        }

 读取字节

 

        #region 方法一:挨个读取字节数组

        using (FileStream fs2 = File.Open(Application.persistentDataPath + "/Lesson3.tang", FileMode.Open, FileAccess.Read))
        {
            //读取第一个整形
            byte[] bytes2 = new byte[4];

            //参数一:用于存储读取的字节数组的容器
            //参数二:容器中开始的位置
            //参数三:读取多少个字节装入容器
            //返回值:当前流索引前进了几个位置
            int index = fs2.Read(bytes2, 0, 4);
            int i = BitConverter.ToInt32(bytes2, 0);
            print("取出来的第一个整数" + i);//999
            print("索引向前移动" + index + "个位置");

            //读取第二个字符串
            //读取字符串字节数组长度
            index = fs2.Read(bytes2, 0, 4);
            print("索引向前移动" + index + "个位置");
            int length = BitConverter.ToInt32(bytes2, 0);
            //要根据我们存储的字符串字节数组的长度 来声明一个新的字节数组 用来装载读取出来的数据
            bytes2 = new byte[length];
            index = fs2.Read(bytes2, 0, length);
            print("索引向前移动" + index + "个位置");
            //得到最终的字符串 打印出来
            print(Encoding.UTF8.GetString(bytes2));
            fs2.Dispose();
        }

        #endregion

        #region 方法二:一次性读取再挨个读取
        print("***************************");
        using (FileStream fs3 = File.Open(Application.persistentDataPath + "/Lesson3.tang", FileMode.Open, FileAccess.Read))
        {
            //一开始就申明一个 和文件字节数组长度一样的容器
            byte[] bytes3 = new byte[fs3.Length];
            fs3.Read(bytes3, 0, (int)fs3.Length);
            fs3.Dispose();
            //读取整数
            print(BitConverter.ToInt32(bytes3, 0));
            //得去字符串字节数组的长度
            int length2 = BitConverter.ToInt32(bytes3, 4);
            //得到字符串
            print(Encoding.UTF8.GetString(bytes3, 8, length2));
        }

更加安全的使用文件流对象

实例:请看写入读取字节部分

        //using关键字重要用法
        //using (申明一个引用对象)
        //{
        //使用对象
        //}
        //无论发生什么情况 当using语句块结束后 
        //会自动调用该对象的销毁方法 避免忘记销毁或关闭流
        //using是一种更安全的使用方法

        //强调:
        //目前我们对文件流进行操作 为了文件操作安全 都用using来进行处理最好

文件夹操作公共类

文件夹相关操作

        //类名:Directory
        //命名空间:using System.IO
        //1.判断文件夹是否存在
        if( Directory.Exists(Application.dataPath + "/数据持久化四"))
        {
            print("存在文件夹");
        }
        else
        {
            print("文件夹不存在");
        }

        //2.创建文件夹
        DirectoryInfo info = Directory.CreateDirectory(Application.dataPath + "/数据持久化四");

        //3.删除文件夹
        //参数一:路径
        //参数二:是否删除非空目录,如果为true,将删除整个目录,如果是false,仅当该目录为空时才可删除
        //Directory.Delete(Application.dataPath + "/数据持久化四");

        //4.查找文件夹和文件
        //得到指定路径下所有文件夹名
        string[] strs = Directory.GetDirectories(Application.dataPath);
        for (int i = 0; i < strs.Length; i++)
        {
            print(strs[i]);
        }

        //得到指定路径下所有文件名
        strs = Directory.GetFiles(Application.dataPath);
        for (int i = 0; i < strs.Length; i++)
        {
            print(strs[i]);
        }

        //5.移动文件夹
        //如果第二个参数所在的路径 已经存在了一个文件夹 那么会报错
        //移动会把文件夹中的所有内容一起移到新的路径
        //Directory.Move(Application.dataPath + "/数据持久化四", Application.dataPath + "/123123123");

 DirectoryInfo和FileInfo

        //DirectoryInfo目录信息类
        //我们可以通过它获取文件夹的更多信息
        //它主要出现在两个地方
        //1.创建文件夹方法的返回值
        DirectoryInfo dInfo = Directory.CreateDirectory(Application.dataPath + "/数据持久化123");
        //全路径
        print(dInfo.FullName);
        //文件名
        print(dInfo.Name);

        //2.查找上级文件夹信息
        dInfo = Directory.GetParent(Application.dataPath + "/数据持久化123");
        //全路径
        print(dInfo.FullName);
        //文件名
        print(dInfo.Name);

        //重要方法
        //得到所有子文件夹的目录信息
        DirectoryInfo[] dInfos = dInfo.GetDirectories();

        //FileInfo文件信息类
        //我们可以通过DirectoryInfo得到该文件下的所有文件信息
        FileInfo[] fInfos = dInfo.GetFiles();
        for (int i = 0; i < fInfos.Length; i++)
        {
            print("**************");
            print(fInfos[i].Name);//文件名
            print(fInfos[i].FullName);//路径
            print(fInfos[i].Length);//字节长度
            print(fInfos[i].Extension);//后缀名
        }

2进制序列化

 声明所需要序列化的对象

//注意:如果要使用C#自带的序列化2进制方法
//申明类时需要添加[System.Serializable]特性
[System.Serializable]
public class Person
{
    public int age = 1;
    public string name = "唐老狮";
    public int[] ints = new int[] { 1, 2, 3, 4, 5 };
    public List<int> list = new List<int>() { 1, 2, 3, 4 };
    public Dictionary<int, string> dic = new Dictionary<int, string>() { { 1,"123"},{ 2,"1223"},{ 3,"435345" } };
    public StructTest st = new StructTest(2, "123");
    public ClssTest ct = new ClssTest();
}

[System.Serializable]
public struct StructTest
{
    public int i;
    public string s;

    public StructTest(int i, string s)
    {
        this.i = i;
        this.s = s;
    }
}

[System.Serializable]
public class ClssTest
{
    public int i = 1;
}

将对象进行2进制序列化

 

        Person p = new Person();
        //方法一:使用内存流得到2进制字节数组
        //主要用于得到字节数组 可以用于网络传输
        //新知识点
        //1.内存流对象
        //类名:MemoryStream
        //命名空间:System.IO
        //2.2进制格式化对象
        //类名:BinaryFormatter
        //命名空间:System.Runtime.Serialization.Formatters.Binary、
        //主要方法:序列化方法 Serialize
        using (MemoryStream ms = new MemoryStream())
        {
            //2进制格式化程序
            BinaryFormatter bf = new BinaryFormatter();
            //序列化对象 生成2进制字节数组 写入到内存流当中
            bf.Serialize(ms, p);
            //得到对象的2进制字节数组
            byte[] bytes = ms.GetBuffer();
            //存储字节
            File.WriteAllBytes(Application.dataPath + "/Lesson5.tang", bytes);
            //关闭内存流
            ms.Close();
        }

        //方法二:使用文件流进行存储
        //主要用于存储到文件中
        using (FileStream fs = new FileStream(Application.dataPath + "/Lesson5_2.tang", FileMode.OpenOrCreate, FileAccess.Write))
        {
            //2进制格式化程序
            BinaryFormatter bf = new BinaryFormatter();
            //序列化对象 生成2进制字节数组 写入到内存流当中
            bf.Serialize(fs, p);
            fs.Flush();
            fs.Close();
        }

2进制反序列化

 反序列化文件中数据

        //主要类
        //FileStream文件流类
        //BinaryFormatter 2进制格式化类
        //主要方法
        //Deserizlize
        //通过文件流打开指定的2进制数据文件
        using (FileStream fs = File.Open(Application.dataPath + "/Lesson5_2.tang", FileMode.Open, FileAccess.Read))
        {
            //申明一个 2进制格式化类
            BinaryFormatter bf = new BinaryFormatter();
            //反序列化
            Person p = bf.Deserialize(fs) as Person;

            fs.Close();
        }

反序列化网络传输过来的2进制数据

        //主要类
        //MemoryStream内存流类
        //BinaryFormatter 2进制格式化类
        //主要方法
        //Deserizlize
        //目前没有网络传输 我们还是直接从文件中获取
        byte[] bytes = File.ReadAllBytes(Application.dataPath + "/Lesson5_2.tang");
        //申明内存流对象 一开始就把字节数组传输进去
        using (MemoryStream ms = new MemoryStream(bytes))
        {
            //申明一个 2进制格式化类
            BinaryFormatter bf = new BinaryFormatter();
            //反序列化
            Person p = bf.Deserialize(ms) as Person;

            ms.Close();
        }

常用加密算法(举例一下种类)

        //MD5算法
        //SHA1算法
        //HMAC算法
        //AES/DES/3DES算法
        //等等等

        //有很多的别人写好的第三发加密算法库
        //可以直接获取用于在程序中对数据进行加密

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Unity中,我们可以使用PlayerPrefs类来进行数据的转换和存取。PlayerPrefs是Unity提供的一个用于本地数据持久化保存和读取的类。它通过key-value的方式将数据保存到本地,类似于字典。可以保存int型、float型和string型的数据,对于bool类型,可以用0和1来代替真和假,以实现保存的目的。使用PlayerPrefs类进行数据转换和存取的步骤如下: 1. 保存数据: 使用PlayerPrefs.SetInt()、PlayerPrefs.SetFloat()、PlayerPrefs.SetString()等方法将数据保存到PlayerPrefs中。例如,使用PlayerPrefs.SetInt("score", 100)将一个整数保存到名为"score"的键值对中。 2. 读取数据: 使用PlayerPrefs.GetInt()、PlayerPrefs.GetFloat()、PlayerPrefs.GetString()等方法从PlayerPrefs中读取保存的数据。例如,使用int score = PlayerPrefs.GetInt("score")可以读取名为"score"的键值对中保存的整数值。 除了PlayerPrefs类,还可以使用其他方法进行数据转换和存取。一种常见的方法是使用BinaryFormatter将对象转换为二进制格式,并通过内存流和文件进行存取。这种方法的步骤如下: 1. 将对象转换为二进制字节数组: 使用MemoryStream和BinaryFormatter类,将对象进行二进制格式化,然后将二进制字节数组写入内存流中。例如,使用BinaryFormatter bf = new BinaryFormatter()和bf.Serialize(ms, person)将对象person转换为二进制字节数组并写入内存流ms中。 2. 存储字节: 使用File.WriteAllBytes()方法,将内存流中的字节数组写入文件。例如,使用File.WriteAllBytes(Application.dataPath + "/Lesson5.mqx", bytes)将字节数组bytes写入名为Lesson5.mqx的文件中。 通过以上方法,我们可以实现Unity数据的转换和存取操作。无论是使用PlayerPrefs类还是其他方法,都可以根据需要选择最适合的方式进行数据转换和存取。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [简单的介绍几种在unity中对数据的存储和读档的方法!](https://blog.csdn.net/qq_41294510/article/details/131536416)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [Unity数据持久化之二进制(之二)](https://blog.csdn.net/qq_52690206/article/details/127791518)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值