【Unity】二进制文件 数据持久化(修改版)【个人复习笔记/有不足之处欢迎斧正/侵删】

        变量的本质都是二进制,在内存中都以字节的形式存储着,通过sizeof方法可以看到常用变量类型占用的字节空间长度(1byte = 8bit,1bit(位)不是0就是1

        二进制文件读写的本质:将各类型变量转换为字节数组,将字节数组直接存储到文件中,不仅可以节约存储空间,提升效率;还可以提升安全性;而且在网络通信中我们直接传输的数据也是字节数据(2进制数据)

BitConverter类

       类名:BitConverter
       命名空间:using System

将各类型转字节

byte[] bytes = BitConverter.GetBytes(666);

字节数组转各类型,第二个参数是索引,从哪一位开始

int i = BitConverter.ToInt32(bytes, 0);

标准编码格式

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

Encoding类

命名空间:using System.Text;

将字符串以指定编码格式转字节

byte[] bytes2 = Encoding.UTF8.GetBytes("HFUTER");

字节数组以指定编码格式转字符串

string s = Encoding.UTF8.GetString(bytes2);

对文件进行操作

File类

C#提供了一个名为File(文件)的公共类,可以快捷的通过代码操作文件相关

命名空间: System.IO

判断文件是否存在

        if(File.Exists(Application.dataPath + "/Unity.wang"))
        {
            print("文件存在");
        }
        else
        {
            print("文件不存在");
        }

创建文件

返回值是一个文件流类

FileStream fs = File.Create(Application.dataPath + "/Unity.shao");

(需要刷新才会在unity中显示)

写入文件

将指定字节数组 写入到指定路径的文件中

        byte[] bytes = BitConverter.GetBytes(999);
        File.WriteAllBytes(Application.dataPath + "/Unity.kun", bytes);

将指定的string数组内容 一行行写入到指定路径中

        string[] strs = new string[] { "lu", "ji", "peng", "kwy"};
        File.WriteAllLines(Application.dataPath + "/Unity.ikun", strs);

将指定字符串写入指定路径

File.WriteAllText(Application.dataPath + "/Unity.kunkun", "cxk");

读取文件

读取字节数据

//返回的也是字节数据
bytes = File.ReadAllBytes(Application.dataPath + "/Unity.lu");

print(BitConverter.ToInt32(bytes, 0));

读取所有行信息

        strs = File.ReadAllLines(Application.dataPath + "/Unity.zhiyin");
        for (int i = 0; i < strs.Length; i++)
        {
            print(strs[i]);
        }

读取所有文本信息

print(File.ReadAllText(Application.dataPath + "/Unity.yuan"));

删除文件(如果删除打开着的文件 会报错)

File.Delete(Application.dataPath + "/Unity.edg");

复制文件

        //参数一:现有文件 需要是流关闭状态
        //参数二:目标文件
        File.Copy(Application.dataPath + "/Unity.yuan", Application.dataPath + "/yuan.tanglaoshi", true);

文件替换

        //参数一:用来替换的路径
        //参数二:被替换的路径
        //参数三:备份路径
        File.Replace(Application.dataPath + "/Unity.yuan", Application.dataPath + "/yuan.ji", Application.dataPath + "/yuan.peng");

以流的形式 打开文件并写入或读取

FileStream fs = File.Open(Application.dataPath + "/Unity.yuan", FileMode.OpenOrCreate, FileAccess.ReadWrite);

参数一:路径
参数二:打开模式
参数三:访问模式

返回的是一个流对象

文件夹

可以在操作系统的文件管理系统中,通过一些操作增删查改文件夹,通过代码的形式,对文件夹进行增删查改

类名:Directory

命名空间:using System.IO

判断文件夹是否存在

Directory.Exists(Application.dataPath + "/json")

创建文件夹

DirectoryInfo info = Directory.CreateDirectory(Application.dataPath + "/json");

删除文件夹

参数一:路径
参数二:是否删除非空目录,如果为true,将删除整个目录,如果是false,仅当该目录为空时才可删除

Directory.Delete(Application.dataPath + "/json");

查找文件夹和文件(得到指定路径下所有文件夹名)

        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]);
        }

移动文件夹
如果第二个参数所在的路径 已经存在了一个文件夹 那么会报错,移动会把文件夹中的所有内容一起移到新的路径

Directory.Move(Application.dataPath + "/json", Application.dataPath + "/999");

DirectoryInfo和FileInfo

DirectoryInfo目录信息类,可以通过它获取文件夹的更多信息

创建文件夹方法的返回值

        DirectoryInfo dInfo = Directory.CreateDirectory(Application.dataPath + "/HFUT");
        //全路径
        print(dInfo.FullName);
        //文件名
        print(dInfo.Name);

查找上级文件夹信息

        dInfo = Directory.GetParent(Application.dataPath + "/HFUT");
        //全路径
        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(fInfos[i].Name);//文件名
            print(fInfos[i].FullName);//路径
            print(fInfos[i].Length);//字节长度
            print(fInfos[i].Extension);//后缀名
        }

文件流

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

类名:FileStream

命名空间:System.IO

方法一:new FileStream

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

方法二:File.Create

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

方法三:File.Open

        //参数一:路径
        //参数二:打开模式
        FileStream fs3 = File.Open(Application.dataPath + "/Lesson.yuan", FileMode.Open);

重要属性和方法

FileStream fs = File.Open(Application.dataPath + "Lesson.yuan", FileMode.OpenOrCreate);

文本字节长度:fs.Length

是否可写:fs.CanRead

是否可读:fs.CanWrite

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

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

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

写入字节

(可写可读的路径,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("HFUTER");
            //先写入长度
            //int length = bytes.Length;
            fs.Write(BitConverter.GetBytes(bytes.Length), 0, 4);
            //再写入字符串具体内容
            fs.Write(bytes, 0, bytes.Length);

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

读取字节

            byte[] bytes2 = new byte[4];

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

            int length = BitConverter.ToInt32(bytes2, 0);
            //要根据存储的字符串字节数组的长度 来声明一个新的字节数组 用来装载读取出来的数据
            bytes2 = new byte[length];
            index = fs2.Read(bytes2, 0, length);
            //因此要先存取长度,然后再读取出来

            print(Encoding.UTF8.GetString(bytes2));
            fs2.Dispose();

索引每次读取了多少位之后,便同时移动这些位

还可以一次性读取后,再挨个读取

一开始就申明一个 和文件字节数组长度一样的容器(如果文件较大,则不推荐使用这种方式去读取)

            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);

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

using关键字重要用法(无论发生什么情况 当using语句块结束后 ,会自动调用该对象的销毁方法 避免忘记销毁或关闭流)


using (申明一个引用对象)
{
使用对象
}

C#类对象的序列化与反序列化

序列化

申明类对象

注意:如果要使用C#自带的序列化2进制方法,申明类时需要添加[System.Serializable]特性

将对象进行2进制序列化

方法一:使用内存流得到2进制字节数组,主要用于得到字节数组,可以用于网络传输

内存流对象

类名:MemoryStream
命名空间:System.IO

2进制格式化对象

类名:BinaryFormatter
命名空间:System.Runtime.Serialization.Formatters.Binary、

主要方法:序列化方法 Serialize

        Person p = new Person();

        using (MemoryStream ms = new MemoryStream())
        {
            //2进制格式化程序
            BinaryFormatter bf = new BinaryFormatter();
            //序列化对象 生成2进制字节数组 写入到内存流当中
            bf.Serialize(ms, p);
            //得到对象的2进制字节数组
            byte[] bytes = ms.GetBuffer();
            //存储字节
            File.WriteAllBytes(Application.dataPath + "/Lesson.t", bytes);
            //关闭内存流
            ms.Close();
        }

方法二:使用文件流进行存储(主要用于存储到文件中)

        using (FileStream fs = new FileStream(Application.dataPath + "/Lesson.t", FileMode.OpenOrCreate, FileAccess.Write))
        {
            //2进制格式化程序
            BinaryFormatter bf = new BinaryFormatter();
            //序列化对象 生成2进制字节数组 写入到内存流当中
            bf.Serialize(fs, p);
            fs.Flush();
            fs.Close();
        }

反序列化

反序列化文件中数据

主要类:
FileStream文件流类
BinaryFormatter 2进制格式化类

主要方法:
Deserizlize
通过文件流打开指定的2进制数据文件

        using (FileStream fs = File.Open(Application.dataPath + "/Lesson.t", 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 + "/Lesson.t");
        //申明内存流对象 一开始就把字节数组传输进去
        using (MemoryStream ms = new MemoryStream(bytes))
        {
            //申明一个 2进制格式化类
            BinaryFormatter bf = new BinaryFormatter();
            //反序列化
            Person p = bf.Deserialize(ms) as Person;

            ms.Close();
        }

C#对象2进制数据加密

当将类对象转换为2进制数据时进行加密,当将2进制数据转换为类对象时进行解密

这样如果第三方获取到2进制数据,不知道加密规则和解密秘钥时就无法获取正确的数据,起到保证数据安全的作用

加密并不是百分百安全可靠,只能提升一定的安全性

常用加密算法

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

最近更新

  1. TCP协议是安全的吗?

    2024-03-12 00:42:02       17 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-12 00:42:02       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-12 00:42:02       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-12 00:42:02       18 阅读

热门阅读

  1. mysql的其他问题

    2024-03-12 00:42:02       21 阅读
  2. 【frp】新版本 frp 参考配置分享

    2024-03-12 00:42:02       20 阅读
  3. C++初学

    C++初学

    2024-03-12 00:42:02      19 阅读
  4. CompletableFuture的使用

    2024-03-12 00:42:02       19 阅读
  5. 复习C++

    2024-03-12 00:42:02       22 阅读
  6. SQL 函数

    2024-03-12 00:42:02       21 阅读
  7. Git - Protocol

    2024-03-12 00:42:02       21 阅读