【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算法等

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/739169.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

day1-C++

1>提示并输入一个字符串&#xff0c;统计该字符中大写、小写字母个数、数字个数、空格个数以及其他字符个数要求使用C风格字符串完成。 代码&#xff1a; #include <iostream> #include <string.h> using namespace std;int main() {string str ;int low 0, …

智慧公厕系统架构分析及应用探索

智慧公厕是运用物联网技术和云计算平台&#xff0c;实现对公共厕所的智能管理和优化的未来式公共厕所信息化整体解决方案。该系统由应用层、平台层、传输层和感知层组成&#xff0c;各层相互配合&#xff0c;共同构建一个高效、智能的公厕运营环境。 一、感知层&#xff1a; …

Android Kotlin知识汇总(三)Kotlin 协程

Kotlin的重要优势及特点之——结构化并发 Kotlin 协程让异步代码像阻塞代码一样易于使用。协程可大幅简化后台任务管理&#xff0c;例如网络调用、本地数据访问等任务的管理。本主题介绍如何使用 Kotlin 协程解决以下问题&#xff0c;从而让您能够编写出更清晰、更简洁的应用代…

Vue基础之Vuex状态管理

个人名片&#xff1a; &#x1f60a;作者简介&#xff1a;一名大二在校生 &#x1f921; 个人主页&#xff1a;坠入暮云间x &#x1f43c;座右铭&#xff1a; 给自己一个梦想&#xff0c;给世界一个惊喜。 &#x1f385;**学习目标: 坚持每一次的学习打卡 文章目录 什么是Vuex&…

Jira自动化的实用工具——ScriptRunner简介及最佳实践

近日&#xff0c;龙智举办的DevSecOps研讨会年终专场“趋势展望与实战探讨&#xff1a;如何打好DevOps基础、赋能创新”在上海圆满落幕。龙智Atlassian技术与顾问咨询团队&#xff0c;以及清晖、JamaSoftware、CloudBees等生态伙伴的嘉宾发表了主题演讲&#xff0c;分享他们在D…

免费分享一套SpringBoot+Vue体育馆(预约)管理系统,帅呆了~~

大家好&#xff0c;我是java1234_小锋老师&#xff0c;看到一个不错的SpringBootVue体育馆(预约)管理系统&#xff0c;分享下哈。 项目视频演示 【免费】SpringBootVue体育馆(预约)管理系统 Java毕业设计_哔哩哔哩_bilibili【免费】SpringBootVue体育馆(预约)管理系统 Java毕…

【高通camera hal bug分析】高通自带相机镜像问题

首先打了两个log&#xff0c;一个是开启镜像的log&#xff0c;还有一个是没有开启镜像的log&#xff0c;如果我们开启镜像以后&#xff0c;观察开启镜像log发现 , 这段代码走的没有任何问题&#xff0c;因为Flip的值等于1了。 关闭镜像log如下&#xff1a; 如果我们不开启镜像…

java中常用的查询算法

1、线性查找 直接从左往右遍历&#xff0c;有则返回 适合数组或链表 public static void main(String[] args) {int[] arr { 12, 34, 32, 56, 78, 23, 34, 56, 67 };int num 34;System.out.println(fangno(arr, num));}public static ArrayList fangno(int[] arr, int num…

Java集合八股文总结

Java集合八股文总结 Collection Set TreeSet 基于红黑树实现&#xff0c;支持有序性操作&#xff0c;例如根据一个范围查找元素的操作。但是查找效率不如 HashSet&#xff0c;HashSet 查找的时间复杂度为 O(1)&#xff0c;TreeSet 则为 O(logN)。HashSet 基于哈希表实现&…

Linux下的系统字体分类

在上次解决Avalo在/usrnia启动问题的时候涉及到了字体&#xff0c;因此特意了解了一下&#xff0c;/share/fonts/目录下存储了不同类型的字体文件&#xff0c;其各代表的意义如下&#xff1a; 我使用的是ubuntu20.04版本&#xff0c;该目录下的文件夹有&#xff1a; /usr/shar…

Google 在 MySQL 中推进矢量搜索,在 LLM 支持方面超越 Oracle

谷歌已将向量搜索引入其 MySQL 数据库服务&#xff0c;这一步领先了 MySQL 的所属公司 Oracle&#xff0c;迄今为止&#xff0c;Oracle 尚未给 MySQL 添加任何大型语言模型&#xff08;LLM&#xff09;方面的功能。 谷歌云数据库副总裁安迪古特曼斯 (Andi Gutmans) 表示&#…

el-form表单中,对非表单内字段增加校验的方法

1、问题说明&#xff1a; 在开发表单的时候&#xff0c;可能会遇到el-form-item中绑定的值不在表单绑定的数据对象中。 此时用prop绑定该字段名是无效的&#xff0c;需要单独对这个字段进行校验。 在el-form-item中有一个属性 error 。用于表单域验证错误信息&#xff0c;设…

Java SE入门及基础(37)

Object 类常用方法 Object类中定义的方法大多数都是属于 native 方法&#xff0c; native 表示的是本地方法&#xff0c;实现方式是在 C 中。 1. getClass() public final Class getClass () //The getClass() method returns a Class object, which has methods you can…

【算法】KY67 整数奇偶排序

描述 输入10个整数&#xff0c;彼此以空格分隔。重新排序以后输出(也按空格分隔)&#xff0c;要求: 1.先输出其中的奇数,并按从大到小排列&#xff1b; 2.然后输出其中的偶数,并按从小到大排列。 输入描述&#xff1a; 任意排序的10个整数&#xff08;0&#xff5e;100&#x…

灰度发布难以追踪?你可能用错了工具

灰度发布进行可观测性的主要方式是通过收集和分析用户在使用新版本产品或服务时的数据&#xff0c;以此来评估新版本的性能、稳定性和用户满意度。这个过程通常包括以下几个步骤&#xff1a; 定义观测指标&#xff1a;首先&#xff0c;需要定义一套合适的观测指标&#xff08;…

Java Day7 常用API

文章目录 1、Arrays1.1 简述1.2 如何比较对象数组1.2.1 方法1.1.2.2 方式2 2、Lambda3、方法引用3.1 静态方法的引用3.2 实例方法引用3.3 特定类型方法引用3.4 构造器引用 1、Arrays 1.1 简述 操作数组的一个工具类 常见方法 int[] arr{10,20,30,50,40};//将 数组的内容 组…

彩色gif闪图怎么做?分享gif动画的方法

在现在的媒体时代&#xff0c;动态图片已经成为了最流行的分享信息的方式。能够传达动态的视觉效果。那种带有动态效果的闪动文字图片要怎么制作呢&#xff1f;很简单&#xff0c;通过使用在线制作闪字图片工具&#xff0c;上传多张文字内容相同&#xff0c;颜色、位置不同的jp…

【网络原理】使用Java基于TCP搭建简单客户端与服务器通信

目录 &#x1f384;API介绍&#x1f338;ServerSocket API&#x1f338;Socket API &#x1f340;TCP中的长短连接&#x1f333;建立TCP回显客户端与服务器&#x1f338;TCP搭建服务器&#x1f338;TCP搭建客户端 ⭕总结 TCP服务器与客户端的搭建需要借助以下API &#x1f384;…

C语言函数—库函数

函数是什么&#xff1f; 数学中我们常见到函数的概念。但是你了解C语言中的函数吗&#xff1f; 维基百科中对函数的定义&#xff1a;子程序 在计算机科学中&#xff0c;子程序&#xff08;英语&#xff1a;Subroutine, procedure, function, routine, method, subprogram, ca…

VSCode调试C++项目时无法显示长字符串的所有内容

记录一次失败的尝试&#xff0c;参考解决vs code 调试golang时字符串显示不全的问题。_golang gin buf数据不全-CSDN博客 但是笔者当前使用的VSCode版本不支持在launch.json中添加dlvLoadConfig选项 笔者的思路是如果VSCode不支持&#xff0c;那就下降到下一层&#xff0c;VSC…