当前位置: 首页 > news >正文

Unity数据持久化

二进制数据持久化的好处:安全、效率高、利于网络通信

文章目录

  • 补充文件夹相关
    • Editor
    • Resources
    • SteammingAsset
  • 序列化和反序列化
    • 序列化
    • 反序列化
  • 二进制数据持久化
    • 转换为字节数据
    • 文件操作
    • 写入字节:
    • 读取字节
    • 安全关闭
    • 文件夹操作
      • 操作文件夹
      • 目录信息和文件信息

补充文件夹相关

Editor

打包是不会将Editor文件打包出去

Resources

  • 打包时会合并Assets目录下的所有Resources的文件,启动程序时对所有对象初始化,构建实例ID这个过程耗时非线性,可能导致启动程序过长,打包完后会进行压缩加密

  • Resources资源在App中,是存储在resources.assetsresources.assets.resSsharedassets0.assetssharedassets0.assets.resS文件中

  • .assets.assets.resS两个后缀文件。同名文件的.assets存储的是序列化文件,类似于Prefab,存储着资源的所有序列化信息,以及对二进制数据源的引用。而.assets.resS里面存储的是二进制数据源,如图片、音效等,是.assets里面所引用的实际的图片、音效等数据。

  • Resources目录下的资源是打包时,未被引用的资源是打包到resources*中,比如新放入的图片还没有使用。而被引用的资源是被打包到sharedassets*,比如被其他Prefab引用的图片。
    在这里插入图片描述

SteammingAsset

只能有一个且位于Assets下,一般放置二进制配置文件,打包时不会被加密压缩,一般用于存储二进制文件
在这里插入图片描述

序列化和反序列化

序列化类对象添加特性:[System.Serializable]字段中的类也需要添加特性

内存流对象:
类对象:MemoryStream
命名空间:System.IO
2进制格式化对象:
类对象:BinaryFormatter
命名空间:System.Runtime.Serialization.Formatters.Binary

序列化

// 方法一:使用内存流
using (MemoryStream ms = new MemoryStream())
{BinaryFormatter bf = new BinaryFormatter();bf.Serialize(ms, animal); // 二进制序列化程序byte[] aniBytes = ms.GetBuffer(); // 获得字节File.WriteAllBytes(path, aniBytes);ms.Close();
}// 方法二:使用文件流
using (FileStream fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write))
{BinaryFormatter bf = new BinaryFormatter();bf.Serialize(fs, animal); // 直接写入文件流fs.Flush();fs.Close();
}

反序列化

// 方法一:文件流
using (FileStream fs = File.Open(path, FileMode.Open, FileAccess.Read))
{BinaryFormatter bf = new BinaryFormatter();Animal an = bf.Deserialize(fs) as Animal; // 返回objectfs.Close();
}// 方法二:内存流(用于网络传输)
using (MemoryStream ms = new MemoryStream(bytes))
{BinaryFormatter bf = new BinaryFormatter();Animal an = bf.Deserialize(ms) as Animal;ms.Close();
}

二进制数据持久化

转换为字节数据

int age = 10;
// 字节数组长度与数据类型的字节数相等
// 【数据转字节】 
byte[] ageByte = BitConverter.GetBytes(age);
// 【字节转数据】
age = BitConverter.ToInt32(ageByte, 0);// 【字符串转字节】
// Encoding.编码格式
byte[] strByte = Encoding.UTF8.GetBytes("111111");
// 【字符串字节转数据】
string str = Encoding.UTF8.GetString(strByte);

文件操作

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

// 【判断文件是否存在】
if (File.Exists(Application.dataPath + "/DataPersistence/Teach1.cs"))
{Debug.Log("存在");
}
//  【创建文件】
// 已经存在的文件不能创建会抛异常
FileStream gfs = File.Create(Application.dataPath + "/DataPersistence/Teach2.txt");// 【写入文件】
// 按字节写入
File.WriteAllBytes(Application.dataPath + "/DataPersistence/Teach2.txt", BitConverter.GetBytes(1024));
// 按行写入字符串数组
string[] strArray = new string[] { "一", "二", "三" };
File.WriteAllLines(Application.dataPath + "/DataPersistence/Teach2.txt", strArray);
// 写入字符串
File.WriteAllText(Application.dataPath + "/DataPersistence/Teach2.txt", "面包");// 【读取文件】
// 读取字节数据
Byte[] bytes = File.ReadAllBytes(Application.dataPath + "/DataPersistence/Teach2.txt");
// 读取所有行字符串
strArray = File.ReadAllLines(Application.dataPath + "/DataPersistence/Teach2.txt");
// 读取文本
string tStr = File.ReadAllText(Application.dataPath + "/DataPersistence/Teach2.txt");// 【删除文件】
File.Delete(Application.dataPath + "/DataPersistence/Teach2.txt");// 【文件流】
// 打开 (路径、文件模式 打开or创建、打开方式 可读可写)
File.Open( Application.dataPath + "/DataPersistence/Teach2.txt", FileMode.OpenOrCreate, FileAccess.Write);

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

基本操作:

// 【创建文件】
// FileMode:打开模式
// CreateNew (创建新文件,如果存在则报错)
// Create (创建新文件,存在则覆盖)
// Open (打开文件,不存在则报错)
// OpenOnCreate (打开文件,不存在则创建)
// Append (存在则打开并查找文件尾,或创建新文件)
// Truncate (打开并清空内容)// FileAccess:访问模式
// None (谢绝共享)
// Read (允许别的程序读取)
// Write (允许别的程序写入)
// ReadWrite (允许别的程序读写)// 方法一:
FileStream fs = new FileStream("teach1.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite);
//方法二:
FileStream gfs = File.Create(Application.dataPath + "/DataPersistence/Teach2.txt");
//方法三:
File.Open( Application.dataPath + "/DataPersistence/Teach2.txt", FileMode.OpenOrCreate,
FileAccess.Write);// 【获得属性】
long fsLength = fs.Length; // 长度
bool canRead = fs.CanRead; // 是否可读
bool canWrite = fs.CanWrite; // 是否可写// 【方法】
fs.Flush(); // 执行完文件后执行,保证文件操作成功进行缓存
fs.Close(); // 关闭流,
fs.Dispose(); // 释放缓存资源

写入字节:

FileStream fs1 = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write);
// 参数:(字节数组,数组开始位置,写入多少个字节)
Byte[] data1 = BitConverter.GetBytes(100);
Byte[] data2 = BitConverter.GetBytes(true);
fs1.Write(data1, 0, 4);
fs1.Write(data2, 0, data2.Length);
// 写入字符串
Byte[] data3 = Encoding.UTF8.GetBytes("Hello World");
int strLength = data3.Length; // 获得字节长度
// 写入字符串的长度
fs1.Write(BitConverter.GetBytes(strLength), 0, sizeof(int)); 
// 写入字符串的长度
fs1.Write(data3, 0, data3.Length); 
fs1.Flush(); // 防止数据丢失
fs1.Dispose(); // 释放资源

读取字节

FileStream fs2 = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Read);
// 方法一:分段读取
Byte[] byte1 = new byte[4];
int streamIndex = fs2.Read(byte1, 0, 4); // 返回流索引
int data1 = BitConverter.ToInt32(byte1);// 读取字符串
Byte[] byte2 = new byte[4];
fs2.Read(byte2, 0, 4);
int strLength = BitConverter.ToInt32(byte2); // 获取字符串长度
Byte[] strBytes = new Byte[strLength];
fs2.Read(strBytes, 0, strLength);
string str = Encoding.UTF8.GetString(strBytes); // 读取字符串内容// 方法二:全部读取
byte[] data = new byte[fs2.Length];
fs2.Read(data, 0, data.Length);fs2.Dispose();

安全关闭

using (FileStream fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write))
{// 语句块执行完之后自动调用Dispose,更加安全
}

文件夹操作

操作文件夹

// 【判断文件夹是否存在】
if (Directory.Exists(path))
{Debug.Log("存在文件夹");
}// 【创建文件夹】
DirectoryInfo df = Directory.CreateDirectory(path);// 【删除文件夹】
// 参数二:是否删除非空目录,true可以删除非空目录,false非空目录不能删除进行报错
Directory.Delete(path, true);// 【查找文件夹】
// 返回该路径下的所有文件夹名
string[] allDirec = Directory.GetDirectories(path); 
// 返回该路径下的所有文件名
string[] allFiles = Directory.GetFiles(path);// 【移动文件夹】
// 参数二路径中的文件夹已存在会报错
// 将目录下的所有文件进行移动
Directory.Move(Application.dataPath + "/TestFile", path);

目录信息和文件信息

类名:DirectoryInfo

DirectoryInfo df = Directory.CreateDirectory(path);
string direcPath = df.FullName; // 文件夹路径
string direcName = df.Name; // 文件夹名
DirectoryInfo dfParent = Directory.GetParent(path); // 得到上级文件夹信息
DirectoryInfo[] sonDf = df.GetDirectories(); // 所有子文件夹目录信息

类名:FileInfo

DirectoryInfo df = Directory.CreateDirectory(path);
string direcPath = df.FullName; // 文件夹路径
string direcName = df.Name; // 文件夹名
DirectoryInfo dfParent = Directory.GetParent(path); // 得到上级文件夹信息
DirectoryInfo[] sonDf = df.GetDirectories(); // 所有子文件夹目录信息FileInfo[] fi = df.GetFiles(); // 得到所有文件信息
foreach (FileInfo fileInfo in fi)
{string fileName = fileInfo.Name; // 文件名string filePath = fileInfo.FullName; // 路径long fileLength = fileInfo.Length; // 字节长度string fileExtension = fileInfo.Extension; // 后缀名
}

http://www.mrgr.cn/news/79144.html

相关文章:

  • 7-4 西安距离
  • 群晖Alist套件无法挂载到群晖webdav,报错【连接被服务器拒绝】
  • 腾讯云开发提供免费GPU服务
  • 简单看看会议系统(TODO)
  • vue2和vue3指令
  • Tensor 基本操作1 | PyTorch 深度学习实战
  • Springboot3整合Redis
  • 工业—使用Flink处理Kafka中的数据_ProduceRecord1
  • 调试android 指纹遇到的坑
  • 右值引用和完美转发【C++11】
  • flask简易版的后端服务创建接口(python)
  • 【时间序列预测】基于Pytorch实现CNN_LSTM算法
  • 典型的调度算法--短作业优先调度算法
  • 写译热点单词
  • STM32 I2C案例2:硬件实现I2C 代码书写
  • 【Linux---10】本地机器 <=> 服务器 文件互传
  • 工业—使用Flink处理Kafka中的数据_ProduceRecord2
  • 【RDMA】RDMA read和write编程实例(verbs API)
  • React第十一节 组件之间通讯之发布订阅模式(自定义发布订阅器)
  • 微信小程序横滑定位元素案例代码
  • 【go】select 语句case的随机性
  • Python矩阵并行计算;CuPy-CUDA 实现显存加速:;在Python中实现显存加速或卸载;CuPy 和 NumPy 区别
  • compose组件库
  • java调用cmdsh命令
  • 流媒体之linux下离线部署FFmpeg 和 SRS
  • MongoDB集群的介绍与搭建