各类型数据和字节数据相互转换
除string类型其余类型转化
//C#提供了一个公共类帮助我们进行转化
//我们只需要记住API即可
//类名:BitConverter
//命名空间:using System
//1.将各类型转字节
byte[] bytes = BitConverter.GetBytes(256);
//2.字节数组转各类型
int i = BitConverter.ToInt32(bytes, 0);
print(i);
string类型
//编码是用预先规定的方法将文字、数字或其它对象编成数码,或将信息、数据转换成规定的电脉冲信号。
//为保证编码的正确性,编码要规范化、标准化,即需有标准的编码格式。
//常见的编码格式有ASCII、ANSI、GBK、GB2312、UTF - 8、GB18030和UNICODE等。
// 说人话
// 计算机中数据的本质就是2进制数据
// 编码格式就是用对应的2进制数 对应不同的文字
// 由于世界上有各种不同的语言,所有会有很多种不同的编码格式
// 不同的编码格式 对应的规则是不同的
// 如果在读取字符时采用了不统一的编码格式,可能会出现乱码
// 游戏开发中常用编码格式 UTF-8
// 中文相关编码格式 GBK
// 英文相关编码格式 ASCII
// 在C#中有一个专门的编码格式类 来帮助我们将字符串和字节数组进行转换
// 类名:Encoding
// 需要引用命名空间:using System.Text;
//1.将字符串以指定编码格式转字节
byte[] bytes2 = Encoding.UTF8.GetBytes("唐老狮");
//2.字节数组以指定编码格式转字符串
string s = Encoding.UTF8.GetString(bytes2);
print(s);
文件相关操作公共类
//C#提供了一个名为File(文件)的公共类
//让我们可以快捷的通过代码操作文件相关
//类名:File
//命名空间: System.IO
文件操作File类的常用内容
//1.判断文件是否存在
if(File.Exists(Application.dataPath + "/UnityTeach.tang"))
{
print("文件存在");
}
else
{
print("文件不存在");
}
//2.创建文件
//FileStream fs = File.Create(Application.dataPath + "/UnityTeach.tang");
//3.写入文件
//将指定字节数组 写入到指定路径的文件中
byte[] bytes = BitConverter.GetBytes(999);
File.WriteAllBytes(Application.dataPath + "/UnityTeach.tang", bytes);
//将指定的string数组内容 一行行写入到指定路径中
string[] strs = new string[] { "123", "唐老狮", "123123kdjfsalk", "123123123125243"};
File.WriteAllLines(Application.dataPath + "/UnityTeach2.tang", strs);
//将指定字符串写入指定路径
File.WriteAllText(Application.dataPath + "/UnityTeach3.tang", "唐老狮哈\n哈哈哈哈123123131231241234123");
//4.读取文件
//读取字节数据
bytes = File.ReadAllBytes(Application.dataPath + "/UnityTeach.tang");
print(BitConverter.ToInt32(bytes, 0));
//读取所有行信息
strs = File.ReadAllLines(Application.dataPath + "/UnityTeach2.tang");
for (int i = 0; i < strs.Length; i++)
{
print(strs[i]);
}
//读取所有文本信息
print(File.ReadAllText(Application.dataPath + "/UnityTeach3.tang"));
//5.删除文件
//注意 如果删除打开着的文件 会报错
File.Delete(Application.dataPath + "/UnityTeach.tang");
//6.复制文件
//参数一:现有文件 需要是流关闭状态
//参数二:目标文件
File.Copy(Application.dataPath + "/UnityTeach2.tang", Application.dataPath + "/唐老狮.tanglaoshi", true);
//7.文件替换
//参数一:用来替换的路径
//参数二:被替换的路径
//参数三:备份路径
File.Replace(Application.dataPath + "/UnityTeach3.tang", Application.dataPath + "/唐老狮.tanglaoshi", Application.dataPath + "/唐老狮备份.tanglaoshi");
//8.以流的形式 打开文件并写入或读取
//参数一:路径
//参数二:打开模式
//参数三:访问模式
//FileStream fs = File.Open(Application.dataPath + "/UnityTeach2.tang", FileMode.OpenOrCreate, FileAccess.ReadWrite);
文件流
//在C#中提供了一个文件流类 FileStream类
//它主要作用是用于读写文件的细节
//FileStream可以以读写字节的形式处理文件
//类名:FileStream
//需要引用命名空间:System.IO
FileStream文件流类常用方法
打开或创建指定文件
//方法一:new FileStream
//参数一:路径
//参数二:打开模式
// CreateNew:创建新文件 如果文件存在 则报错
// Create:创建文件,如果文件存在 则覆盖
// Open:打开文件,如果文件不存在 报错
// OpenOrCreate:打开或者创建文件根据实际情况操作
// Append:若存在文件,则打开并查找文件尾,或者创建一个新文件
// Truncate:打开并清空文件内容
//参数三:访问模式
//参数四:共享权限
// None 谢绝共享
// Read 允许别的程序读取当前文件
// Write 允许别的程序写入该文件
// ReadWrite 允许别的程序读写该文件
//FileStream fs = new FileStream(Application.dataPath + "/Lesson3.tang", FileMode.Create, FileAccess.ReadWrite);
//方法二:File.Create
//参数一:路径
//参数二:缓存大小
//参数三:描述如何创建或覆盖该文件(不常用)
// Asynchronous 可用于异步读写
// DeleteOnClose 不在使用时,自动删除
// Encrypted 加密
// None 不应用其它选项
// RandomAccess 随机访问文件
// SequentialScan 从头到尾顺序访问文件
// WriteThrough 通过中间缓存直接写入磁盘
//FileStream fs2 = File.Create(Application.dataPath + "/Lesson3.tang");
//方法三:File.Open
//参数一:路径
//参数二:打开模式
//FileStream fs3 = File.Open(Application.dataPath + "/Lesson3.tang", FileMode.Open);
重要属性和方法
//FileStream fs = File.Open(Application.dataPath + "Lesson3.tang", FileMode.OpenOrCreate);
//文本字节长度
//print(fs.Length);
//是否可写
//if( fs.CanRead )
//{
//}
//是否可读
//if( fs.CanWrite )
//{
//}
//将字节写入文件 当写入后 一定执行一次
//fs.Flush();
//关闭流 当文件读写完毕后 一定执行
//fs.Close();
//缓存资源销毁回收
//fs.Dispose();
写入字节
字符串写入时需要字符串的长度信息,所以一般都会在用其他变量记录长度
print(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("唐老狮哈哈哈哈");
//先写入长度
//int length = bytes.Length;
fs.Write(BitConverter.GetBytes(bytes.Length), 0, 4);
//再写入字符串具体内容
fs.Write(bytes, 0, bytes.Length);
//避免数据丢失 一定写入后要执行的方法
fs.Flush();
//销毁缓存 释放资源
fs.Dispose();
}
读取字节
#region 方法一:挨个读取字节数组
using (FileStream fs2 = File.Open(Application.persistentDataPath + "/Lesson3.tang", FileMode.Open, FileAccess.Read))
{
//读取第一个整形
byte[] bytes2 = new byte[4];
//参数一:用于存储读取的字节数组的容器
//参数二:容器中开始的位置
//参数三:读取多少个字节装入容器
//返回值:当前流索引前进了几个位置
int index = fs2.Read(bytes2, 0, 4);
int i = BitConverter.ToInt32(bytes2, 0);
print("取出来的第一个整数" + i);//999
print("索引向前移动" + index + "个位置");
//读取第二个字符串
//读取字符串字节数组长度
index = fs2.Read(bytes2, 0, 4);
print("索引向前移动" + index + "个位置");
int length = BitConverter.ToInt32(bytes2, 0);
//要根据我们存储的字符串字节数组的长度 来声明一个新的字节数组 用来装载读取出来的数据
bytes2 = new byte[length];
index = fs2.Read(bytes2, 0, length);
print("索引向前移动" + index + "个位置");
//得到最终的字符串 打印出来
print(Encoding.UTF8.GetString(bytes2));
fs2.Dispose();
}
#endregion
#region 方法二:一次性读取再挨个读取
print("***************************");
using (FileStream fs3 = File.Open(Application.persistentDataPath + "/Lesson3.tang", FileMode.Open, FileAccess.Read))
{
//一开始就申明一个 和文件字节数组长度一样的容器
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);
//得到字符串
print(Encoding.UTF8.GetString(bytes3, 8, length2));
}
更加安全的使用文件流对象
实例:请看写入读取字节部分
//using关键字重要用法
//using (申明一个引用对象)
//{
//使用对象
//}
//无论发生什么情况 当using语句块结束后
//会自动调用该对象的销毁方法 避免忘记销毁或关闭流
//using是一种更安全的使用方法
//强调:
//目前我们对文件流进行操作 为了文件操作安全 都用using来进行处理最好
文件夹操作公共类
文件夹相关操作
//类名:Directory
//命名空间:using System.IO
//1.判断文件夹是否存在
if( Directory.Exists(Application.dataPath + "/数据持久化四"))
{
print("存在文件夹");
}
else
{
print("文件夹不存在");
}
//2.创建文件夹
DirectoryInfo info = Directory.CreateDirectory(Application.dataPath + "/数据持久化四");
//3.删除文件夹
//参数一:路径
//参数二:是否删除非空目录,如果为true,将删除整个目录,如果是false,仅当该目录为空时才可删除
//Directory.Delete(Application.dataPath + "/数据持久化四");
//4.查找文件夹和文件
//得到指定路径下所有文件夹名
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]);
}
//5.移动文件夹
//如果第二个参数所在的路径 已经存在了一个文件夹 那么会报错
//移动会把文件夹中的所有内容一起移到新的路径
//Directory.Move(Application.dataPath + "/数据持久化四", Application.dataPath + "/123123123");
DirectoryInfo和FileInfo
//DirectoryInfo目录信息类
//我们可以通过它获取文件夹的更多信息
//它主要出现在两个地方
//1.创建文件夹方法的返回值
DirectoryInfo dInfo = Directory.CreateDirectory(Application.dataPath + "/数据持久化123");
//全路径
print(dInfo.FullName);
//文件名
print(dInfo.Name);
//2.查找上级文件夹信息
dInfo = Directory.GetParent(Application.dataPath + "/数据持久化123");
//全路径
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("**************");
print(fInfos[i].Name);//文件名
print(fInfos[i].FullName);//路径
print(fInfos[i].Length);//字节长度
print(fInfos[i].Extension);//后缀名
}
2进制序列化
声明所需要序列化的对象
//注意:如果要使用C#自带的序列化2进制方法
//申明类时需要添加[System.Serializable]特性
[System.Serializable]
public class Person
{
public int age = 1;
public string name = "唐老狮";
public int[] ints = new int[] { 1, 2, 3, 4, 5 };
public List<int> list = new List<int>() { 1, 2, 3, 4 };
public Dictionary<int, string> dic = new Dictionary<int, string>() { { 1,"123"},{ 2,"1223"},{ 3,"435345" } };
public StructTest st = new StructTest(2, "123");
public ClssTest ct = new ClssTest();
}
[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 ClssTest
{
public int i = 1;
}
将对象进行2进制序列化
Person p = new Person();
//方法一:使用内存流得到2进制字节数组
//主要用于得到字节数组 可以用于网络传输
//新知识点
//1.内存流对象
//类名:MemoryStream
//命名空间:System.IO
//2.2进制格式化对象
//类名:BinaryFormatter
//命名空间:System.Runtime.Serialization.Formatters.Binary、
//主要方法:序列化方法 Serialize
using (MemoryStream ms = new MemoryStream())
{
//2进制格式化程序
BinaryFormatter bf = new BinaryFormatter();
//序列化对象 生成2进制字节数组 写入到内存流当中
bf.Serialize(ms, p);
//得到对象的2进制字节数组
byte[] bytes = ms.GetBuffer();
//存储字节
File.WriteAllBytes(Application.dataPath + "/Lesson5.tang", bytes);
//关闭内存流
ms.Close();
}
//方法二:使用文件流进行存储
//主要用于存储到文件中
using (FileStream fs = new FileStream(Application.dataPath + "/Lesson5_2.tang", FileMode.OpenOrCreate, FileAccess.Write))
{
//2进制格式化程序
BinaryFormatter bf = new BinaryFormatter();
//序列化对象 生成2进制字节数组 写入到内存流当中
bf.Serialize(fs, p);
fs.Flush();
fs.Close();
}
2进制反序列化
反序列化文件中数据
//主要类
//FileStream文件流类
//BinaryFormatter 2进制格式化类
//主要方法
//Deserizlize
//通过文件流打开指定的2进制数据文件
using (FileStream fs = File.Open(Application.dataPath + "/Lesson5_2.tang", 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 + "/Lesson5_2.tang");
//申明内存流对象 一开始就把字节数组传输进去
using (MemoryStream ms = new MemoryStream(bytes))
{
//申明一个 2进制格式化类
BinaryFormatter bf = new BinaryFormatter();
//反序列化
Person p = bf.Deserialize(ms) as Person;
ms.Close();
}
常用加密算法(举例一下种类)
//MD5算法
//SHA1算法
//HMAC算法
//AES/DES/3DES算法
//等等等
//有很多的别人写好的第三发加密算法库
//可以直接获取用于在程序中对数据进行加密