Unity学习笔记数据持久化之二进制

本文介绍了C#中字节数组与各类数据的转换,如BitConverter和Encoding类的应用,同时详细讲解了文件操作(包括File和FileStream类)、文件夹管理、以及C#对象的序列化与反序列化过程,涵盖了数据安全、效率和存储优化等内容。
摘要由CSDN通过智能技术生成

优点

(1)安全性较高。(2)效率较高。(3)节约存储空间。

各类型转字节数组

一.各类型数据和字节数据相互转化

C#提供了一个公共类帮助我们进行转化

类名:BitConverter

命名空间:using System

(1)将各类型转字节

byte[] bytes=BitConverter.GetBytes(256);
每一位代表二进制八位
print(bytes[0])  //0
pirnt(bytes[1])  //1

(2)字节数组转各类型

int i=BitConverter.ToInt32(bytes,0);
第二个参数代表从第几个索引开始

二.标准编码格式

游戏开发中常用编码格式 UTF-8

中文相关编码格式 GBK

英文相关编码格式 ASCII

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

类名:Encoding

需要引用的命名空间:using System.Text

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

byte[] bytes2 = Encoding.UTF8.GetBytes("你好")

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

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

文件操作

C#提供了一个名为File(文件)的公共类

类名:File

命名空间:System.IO

一.文件操作File类的常用内容

//(1)判断文件是否存在

File.Exists(Application.dataPath+“/data.txt”);

//(2)创建文件

FileStream fs =File.Create(Application.dataPath+"/data.txt");

//(3)写入文件

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

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

File.WriteAllBytes(Application,dataPath+"/data.txt");

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

string[] strs=new string[]{"123","你好"};

File.WriteAllLines(application.dataPath+"/data.txt",strs);

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

File.WriteAllText(Application.dataPath+"/data.txt","你好/n哈哈哈");

//(4)读取文件

//读取字节数据

bytes = File.ReadAllBytes(Application.dataPath+"/data.txt");

//读取所有行信息

strs = File.ReadAllLines(Application.dataPath+"/data.txt");

//读取所有文本信息

print(File.ReadAllText(Application.dataPath+"/data.txt"));

//(5)删除文件

//注意:如果删除打开着的文件会报错

File.Delete(Application.dataPath+"/data,txt");

//(6)复制文件

//参数一:现有文件 需要是流关闭状态

//参数二:目标文件

//参数三:一个布尔值,用于指定是否覆盖目标文件(如果目标文件存在)。

File.Copy(Apllication.dataPath+"/datra.txt",Application.dataPath+"/data2.txt",true);

//(7)文件替换

//参数一:用来替换的路径

//参数二:被替换的路径

//参数三:备份路径

File.Replace(Apllication.dataPath+"/datra.txt",Application.dataPath+"/data2.txt",Application.dataPath+"/data3.txt");

//(8)以流的形式打开文件并写入或读取

//参数一:路径

//参数二:打开模式

//参数三:访问模式

FileStream fs =File.Open(Apllication.dataPath+"/datra.txt",FileMode.OpenOrCreate,FIleAccess.ReadWrite);

二.文件操作相关文件流

(1)什么是文件流

文件里面存储的数据就像是一条数据流(数组或者列表),可以通过FileStream一部分一部分的读写数据流。比如可以先存一个int(4字节),再存一个bool(1字节),再存一个string(n字节)。利用FileStream可以以流式逐个读写。

类名:FileStream

命名空间:System.IO

(2)打开或创建指定文件
//方法一:newFileStream

//参数一:路径

//参数二:打开模式

// CreateNew:创建新文件,如果文件存在,则报错

// Create:创建文件,如果文件存在,则覆盖

// Open:打开文件,如果文件不存在,则报错

// OpenOrCreate:打开或者创建文件,根据实际情况操作

// Append:若存在文件,则打开并查找文件尾,或者创建一个新文件

// Truncate:打开并清空文件内容

//参数三:访问模式

//参数四:共享权限(很少使用)

// None 谢绝共享

// Read 允许别的程序读取当前文件

// Write 允许别的程序写入该文件

// ReadWrite 允许别的程序读写该文件

FileStream fs = new FileStream(Application.dataPath+"/data.txt",FileMode.Create,FileAccess.ReadWrite,

FileShare.ReadWrite);

//方法二:File.Create

//参数一:路径

//参数二:缓存大小

//参数三:描述如何创建或覆盖该文件(不常用)

// Asynchronous 可用于异步读写

// DeleteOnClose 不在使用时,自动删除

// Encrypted 加密

// None 不应用其他选项

// RandomAccess 随机访问文件

// SequentialScan 从头到尾顺序访问文件

// WriteThrough 通过中间缓存直接写入磁盘

FileStream fs2=File.Create(Application.dataPath+"/data.txt");

//方法三:File.Open

//参数一:路径

//参数二:打开模式

FileStream fs3=File.Open(Application.dataPath+"/data.txt",FileMode.Open);
(3)重要属性和方法
//文本字节长度

print(fs.Length);

//是否可写

if( fs.CanRead )

{

}

//是否可读

if( fs.CanWrite )

{

}

//将字节写入文文件,当写入后,一定执行一次

fs.Flush();

//关闭流,当文件读写完毕后,一定执行

fs.Close();

//缓存资源销毁回收

fs.Dispose();
(4)写入字节
FileStream fs= new FileStream(Application.persistentDataPath+"/data.txt",FileMode.OpenOrCreate,FlieAccess.Write);

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

//方法:Write

//参数一:写入的字节数组

//参数二:数组中的开始索引

//参数三:写入多少个字节

fs.Write(bytes,0,bytes.Length);

//写入字符串时

bytes=Encoding.UTF8.GetBytes("你好");

//先写入长度

fs.Write(BitConverter.GetBytes(bytes.Length),0,4);

//再写入字符串具体内容

fs.Write(bytes,0,bytes.Length);

//避免数据丢失 一定写入后要执行的方法

fs.Flush();

//销毁缓存 释放资源

fs.Dispose();
(5)读取字节
FileStream fs2 = File.Open(Application.persistentDataPath+"/data.txt",FileMode.Open,FileAcces.Read);

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

//读取第一个整形

byte[] bytes2 = new bytye[4];

//参数一:用于读取存储

//参数二:容器中开始的位置

//参数三:读取多少个字节装入容器

//返回值:当前流索引前进了几个位置

int index = fs2.Read(bytes2,0,4);

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

//读取第二个字符串

//去读字符串字节数组长度

index=fs.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));

//方法二:一次性读取再挨个读取

FileStream fs3 = File.Open(Application.persistentDataPath+"/data.txt",FileMode.Open,FileAcces.Read);

//一开始就申明一个和文件字节数组长度一样的容器

byte[] bytes3 = new byte[fs3.Length];

fs3.Read(bytes3,0,(int)fs3.Length);

fs3.Dispose();

//读取整数

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

//得到字符串字节数组的长度

int lengrh2 = BitConverter.ToInt32(bytes3,4);

//得到字符串

print(Encoding.UTF8.GetString(bytes3,8,length2));
(6)更加安全的使用文件流对象
//using关键字重要用法

using(申明一个引用对象)

{

//使用对象

}

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

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

三.文件操作相关文件夹

(1)文件夹操作公共类

类名:Directory

命名空间:using System.IO

//判断文件夹是否存在

if(Directory.Exists(Application.dataPath+"/数据持久化");

{

print("存在文件夹");

}

//创建文件夹

DirectoryInfo info =Directory.CreateDirectory(Application.dataPath+"/数据持久化");

//删除文件夹

//参数一:路径

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

Directory.Delete(Application.dataPath+"/数据持久化");

//查找文件夹和文件

//得到指定路径下所有文件夹名

string[] strs = Directory.GetDirectories(Application.dataPath);

for(int i=0;i

{

print(strs[i]);

}

//得到指定路径下所有文件名

strs = Directory.GetFiles(Application.dataPath);

for(int i=0;i

{

print(strs[i]);

}

//移动文件夹

//如果第二个参数所在的路径,已经存在了一个文件夹,那么会报错

//移动会把文件夹中的所有内容一起移动到新的路径

Directory.Move(Applicaiton.dataPath+"/数据持久化",Applicaition.dataPath+"/123");
(2)DirectoryInfo和FieInfo

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

他主要出现在两个地方:1.创建文件夹方法的返回值。2.查找上级文件夹信息

//1.创建文件夹方法的返回值

DirectoryInfo info=Dectory.CreateDirectory(Application.dataPath+"/数据持久化");

//全路径

print(info.FullName);

//文件名

print(info.Name);

//2.查找上级文件夹信息

info=Directory.GetParent(Application.dataPath+"/数据持久化");

//全路径

print(info.FullName);

//文件名

print(info.Name);

重要方法

//得到所有子文件夹的目录信息

DirectoryInfo[] dinfos=info.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#对象的序列化与序列化

要使用C#自带的序列化二进制方法,在申明类时需要添加[System.Serializable]特性

[System.Serializable]

public class Person

{

public int age = 1;

public string name = "某某某";

public int[] ints = new int[] {1,2,3};

public List list = new List(){1,2,3,4,5};

public Dictionary dic = new Dictionary(){{1,"123"},{2,"12344"}};

public StructTest st = new StructTest(2,"123");

public ClassTest ct = new ClassText();

}

[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 ClassTest

{

public int i = 1;

}

一.二进制序列化

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

1.内存流对象

类名:MemoryStream

命名空间:System.IO

2.二进制格式化对象

类名:BinaryFormatter

命名空间:System.Runtime.Serialization.Formatters.Binary

主要方法:序列化方法 Serialize

Person p=new Person();

using (MemoryStream ms = new MemoryStream())

{

//二进制格式化程序

BinaryFormatter bf = new BinaryFormatter();

//序列化对象 生成二进制字节数组 写入到内存流当中

bf.Serialize(ms,p);

//得到对象的二进制字节数组

byte[] bytes = ms.GetBuffer();

//存储字节

File.WriteAllBytes(Application.dataPath+"/data.txt",bytes);

//关闭内存流

ms.Close();

}

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

using (FileStream fs = new FileStream(Application.dataPath+"/data.txt",FileMode.OpenOrCreate,FileAccess.Write))

{

//二进制格式化程序

BinaryFormatter bf = new BinaryFormatter();

//序列化对象 生成二进制字节数组 写入到内存流中

bf.Serialize(fs,p);

fs.Flush();

fs.Close();

}

二.二进制反序列化

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

//通过文件流打开指定的二进制数据文件

using (FileStream fs = File.Open(Application.dataPath+"/data.txt",FileMode.Open,FileAccess.Read))

{

//申明一个二进制格式化类

BinaryFormatter bf = new BinaryFormatter();

//反序列话

Person p = bf.Deserialize(fs) as Person;

fs.Close();

}

byte[] bytes = File.ReadAllBytes(Application.dataPath+"/data.txt");

//申明缓存流对象 一开始就把字节数组传输进去

using (MemoryStream ms = new MemoryStream(bytes))

{

//申明一个二进制格式化类

BinaryFormatter bf = new BinaryFormatter();

//反序列化

Person p = bf.Deserizlize(ms) as Person;

ms.Close();

}

  • 13
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值