优点
(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();
}