学习UE的FArchive的最基础功能

目标

尝试FArchive的最基础功能。代码参考这里

0. FArchive是什么?

源代码里FArchive的注释如下:
Base class for archives that can be used for loading, saving, and garbage collecting in a byte order neutral way

  • 它是 archive 的基类。(archive直译为“档案”,我理解是“存储数据的载体”)
  • 读取、保存、垃圾回收的过程中发挥作用。
  • 字节顺序这样 neutral 的方式。(neutral直译为“中立的”,我理解是“通用的,并不特定针对于某一类型的”)

最常见的出现场合,应该是UObject序列化逻辑了。(“序列化”简单来说就是将自己的数据能保存下来,以便下次能读取回来)
在这里插入图片描述

1. 简单代码测试例:保存数据到文件

测试将一些数据写入文件:

  • 首先,定义一些待存储的数据
  • 然后,使用CreateFileWriter来创建一个用于保存数据的Archive
  • 最后,序列化数据。
//一些测试数据:
float TestF = 3.69;
FVector TestV = FVector(0.9, 0.5, 0.7);
FString TestS = "yak";
//创建用来保存数据的Archive
FArchive* TestArchive = IFileManager::Get().CreateFileWriter(TEXT("D:/Temp/TestArchive.dat"));
//序列化:
if (TestArchive)
{
    
    
	*TestArchive << TestF;
	*TestArchive << TestV;
	*TestArchive << TestS;
	TestArchive->Close();
}

运行后,可以看到文件被保存下来
在这里插入图片描述

2. 简单代码测试例:从文件读取数据

测试从刚才的文件中读取数据:

  • 首先,由于数据是需要从文件读取出来的,而非定义的,所以开头只需要初始化即可。
  • 然后,使用CreateFileReader来创建一个用于读取数据的Archive
  • 最后,反序列化数据,需要注意,这里和序列化时完全一样
//初始化测试数据的值:
float TestF = 0;
FVector TestV = FVector(0, 0, 0);
FString TestS = "";
//创建用来保存数据的Archive
FArchive* TestArchive = IFileManager::Get().CreateFileReader(TEXT("D:/Temp/TestArchive.dat"));
//反序列化:
if (TestArchive)
{
    
    
	*TestArchive << TestF;
	*TestArchive << TestV;
	*TestArchive << TestS;
	TestArchive->Close();
}
//打印这些值看看:
UE_LOG(LogTemp, Warning, TEXT("TestF:%f TestV:%s TestS:%s"), TestF, *TestV.ToString(), *TestS);

运行后,可以看到能正确读取到之前的数据:
在这里插入图片描述

3. 为什么“反序列化”的代码和“序列化”的代码完全一样?

首先,从设计来说,读取必须一样。因为数据是按照顺序存入的,那么读取时也必须是一样的顺序。
如果尝试用不一样的顺序读取,则会有报错,且数据读取错误:
在这里插入图片描述


其次,从代码实现上讲,能做到完全一样是因为:不同的FArchive子类可以对<<操作有不同的逻辑。
比如,保存时,使用CreateFileWriter创建出来的是FArchiveFileWriterGeneric子类:
在这里插入图片描述
读取时,使用CreateFileReader创建出来的是FArchiveFileReaderGeneric
在这里插入图片描述


这样,各种UObject序列化的代码只需要一个函数。这样不仅减少了代码维护,更重要的是能绝对保证反序列化时能与序列化有一致的顺序。

猜你喜欢

转载自blog.csdn.net/u013412391/article/details/131866086