UE4中文本文件配置文件Json文件XML文件的读写

2 篇文章 0 订阅

虚幻引擎中提供了与平台无关的文件读写与访问接口,通过调用,可以完成一些文件的读写。比如文本文件,配置文件,json文件,xml文件等。

完成文件读写,首先需要获取文件路径等相关信息。对调用这些操作,我们需要包含头文件PlatformFilemanager.h和FileHelper.h。对于json文件读写,我们需要在.build.cs文件中添加Json和JsonUtilities两个模块;对于xml文件读取,我们需要在.build.cs文件中添加XmlParser模块。引用相关模块后,在具体实现需要引入对应的头文件。我们可以创建一个继承自UBlueprintFunctionLibrary的C++类,这样我们就可以在蓝图中调用我们在C++中声明BlueprintCallable创建的函数。

需要引入的头文件:

#include "PlatformFilemanager.h"
#include "FileHelper.h"

#include "Json.h"
#include "JsonObject.h"
#include "JsonSerializer.h"

#include"Runtime/XmlParser/Public/XmlFile.h"
#include"Runtime/XmlParser/Public/XmlNode.h"

函数方法声明(FunctionLIbrary.h):

//文本文件读写
	UFUNCTION(BlueprintCallable, Category = "Test")
		static void WriteText(FString path,FString data);
	UFUNCTION(BlueprintCallable, Category = "Test")
		static FString ReadText(FString path);

	//配置文件读写
	UFUNCTION(BlueprintCallable, Category = "Test")
		static void WriteConfig(FString section, FString name, FString value, FString path);
	UFUNCTION(BlueprintCallable, Category = "Test")
		static FString ReadConfig(FString section, FString name, FString path);

	//UE4读取json文件
	UFUNCTION(BlueprintCallable, Category = "Test")
		static void NonSeriWriteJson();
	UFUNCTION(BlueprintCallable, Category = "Test")
		static void SeriWriteJson();
	UFUNCTION(BlueprintCallable, Category = "Test")
		static TArray<FName> ReadJson();

	//UE4读取xml文件
	UFUNCTION(BlueprintCallable, Category = "Test")
		static void CreateXmlFile();
	UFUNCTION(BlueprintCallable, Category = "Test")
		static void ReadXmlFile(const FString &XmlPath);

函数方法实现(FunctionLibrary.cpp):

void UFunctionLibrary::WriteText(FString path, FString data){
	FString ProjectDir = FPaths::GameDir();
	ProjectDir += path;
	if (!ProjectDir.Contains(".txt")) {
		ProjectDir += ".txt";
	}
	FFileHelper::SaveStringToFile(data, *ProjectDir);
}

FString UFunctionLibrary::ReadText(FString path){
	FString data;
	FString ProjectDir = FPaths::GameDir();
	ProjectDir += path;
	if (!ProjectDir.Contains(".txt")) {
		ProjectDir += ".txt";
	}
	if (!FPlatformFileManager::Get().GetPlatformFile().FileExists(*ProjectDir)) {
		GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("Couldn't find file"));
		return FString();
	}
	else {
		GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("Could find file"));
		FFileHelper::LoadFileToString(data, *ProjectDir);
		return data;
	}
}

void UFunctionLibrary::WriteConfig(FString section, FString name, FString value, FString path){
	if (!path.Contains(".ini")) {
		path += ".ini";
	}
	GConfig->SetString(*section, *name, *value, FPaths::GameDir() / *path);
}

FString UFunctionLibrary::ReadConfig(FString section, FString name, FString path){
	FString result;
	if (!path.Contains(".ini")) {
		path += ".ini";
	}
	GConfig->GetString(*section, *name, result, FPaths::GameDir() / *path);
	return result;
}

void UFunctionLibrary::NonSeriWriteJson()
{
	FString FilePath = FPaths::GameDir() + TEXT("MyJson.json");
	FString jsonStr;
	TSharedRef<TJsonWriter<>> jsonWriter = TJsonWriterFactory<>::Create(&jsonStr);
	jsonWriter->WriteObjectStart();
	jsonWriter->WriteValue(TEXT("json"), TEXT("jsonValue"));
	jsonWriter->WriteObjectEnd();
	jsonWriter->Close();
	FFileHelper::SaveStringToFile(jsonStr, *FilePath);
}

void UFunctionLibrary::SeriWriteJson()
{
	TSharedPtr<FJsonObject> RootObj = MakeShareable(new FJsonObject());
	RootObj->SetStringField("root", "000");
	TArray<TSharedPtr<FJsonValue>> arrValue;
	TSharedPtr<FJsonValueString> tmp = MakeShareable(new FJsonValueString("element"));
	arrValue.Add(tmp);
	RootObj->SetArrayField("array", arrValue);
	FString FilePath = FPaths::GameDir() + TEXT("MySeri.json");
	FString jsonStr;
	TSharedRef<TJsonWriter<TCHAR>> jsonWriter = TJsonWriterFactory<TCHAR>::Create(&jsonStr);
	FJsonSerializer::Serialize(RootObj.ToSharedRef(), jsonWriter);
	FFileHelper::SaveStringToFile(jsonStr, *FilePath);
}

TArray<FName> UFunctionLibrary::ReadJson()
{
	FString FilePath = FPaths::GameDir() + TEXT("MyJson.json");
	if (FPaths::FileExists(FilePath))
	{
		FString section1;
		FString section2;
		FString section3;
		FString section4;
		TArray<FName> jsonData;
		FString fileStr;
		FFileHelper::LoadFileToString(fileStr, *FilePath);
		TSharedPtr<FJsonObject> rootObject = MakeShareable(new FJsonObject());
		TSharedRef<TJsonReader<>> jsonReader = TJsonReaderFactory<>::Create(fileStr);
		if (FJsonSerializer::Deserialize(jsonReader, rootObject))
		{
			section1 = rootObject->GetStringField("json");
			section2 = rootObject->GetStringField("xml");
			section3 = rootObject->GetStringField("text");
			section4 = rootObject->GetStringField("config");
		}
		jsonData.Add(FName(*section1));
		jsonData.Add(FName(*section2));
		jsonData.Add(FName(*section3));
		jsonData.Add(FName(*section4));
		return jsonData;
	}
	return TArray<FName>();
}

void UFunctionLibrary::CreateXmlFile()
{
	const FString XmlContent = "<DocumentElement>\n<Infor>\n< ID>xml </ID >\n<Name>file</Name>\n<Content>cccc</Content>\n</Infor>\n</DocumentElement>";
	FXmlFile* WriteXml = new FXmlFile(XmlContent, EConstructMethod::ConstructFromBuffer);
	if (WriteXml == nullptr)
	{
		GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, TEXT("fail!"));
		return;
	}
	WriteXml->Save(FPaths::GameDir() + "xml.xml");
	GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Blue, TEXT("succeed!"));
}

void UFunctionLibrary::ReadXmlFile(const FString &XmlPath)
{
	FXmlFile* XmlFile = new FXmlFile(XmlPath);
	FXmlNode* RootNode = XmlFile->GetRootNode();
	const TArray<FXmlNode*> AssetNodes = RootNode->GetChildrenNodes();
	for (FXmlNode* node : AssetNodes)
	{
		const TArray<FXmlNode*> ChildNodes = node->GetChildrenNodes();
		FString AssetContent = node->GetContent();
		GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, AssetContent);
		for (FXmlNode* node : ChildNodes)
		{
			FString ChildContent = node->GetContent();
			GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Blue, ChildContent);
		}
	}
}

备注(若干函数类和方法介绍):

  • FPaths::GameContentDir()返回当前工程Content文件夹路径
  • TJsonWriter<>是UE4专门用于写Json的模板类,类型常用参数为TCHAR,主要方法有:
函数作用
Close()关闭写工具
WriterArrayStart()开始一个Json数组
WriterArrayEnd()结束一个Json数组
WriterNull(FString)为一个键写入空值
WriterObjectStart()开始一个Json对象
WriterObjectEnd()结束一个Json对象
WriterValue(FString,FString/int32/float/bool)向Json文件写入键值对
  • TJsonWriterFactory<>Create(FString)是UE4用来生成Json写工具TJsonWriter<>的类。TJsonFactory<>只有一个方法Create;
  • FFileHelper是UE4中文件读写工具,方法SaveStringToFile(TJsonWriter*,FString*)作用是将Json写工具中的Json数据写到FString字符串的路径文件中。
  • 使用非序列化方式写入Json时,写入方式需要严格按照Json的语法格式来做,如最开始需要使用WriterObjectStart()创建一个根前括号,即Json语法中最外面一层的{,所有写入结束后需要使用WriterObjectEnd()声明根对象结束,即Json语法中的最外面一层的},同理数组也需要按对象一样的方法进行处理。如此才能写入一个结构完整的Json文本。
  • 序列化的写入方式则无需考虑按照Json的语法结构进行写入,序列化的写入方式是通过一个FJsonObject对象进行Json文本写入。
  • 序列化写好的FJsonObject对象需要转换为FString字符串才能向文本中写入数据,FJsonObject转化为FString输入流的方式是FJsonSerializer::Serialize(TSharePtr<FJsonObject>.ToShareRef(),TSharePtr<FJsonWriter>);其中TSharePtr<FJsonWriter>和非序列化写入一样需要绑定一个FString作为输入流载体。
  • Json文本的读取,需要将Json文本以字符串的形式读入到一个FString的输入流载体中,然后将这个输入流载体绑定到TJsonReader<>读工具上,然后使用FJsonSerializer::Deserialize(TSharePtr<TJsonReader<>>,TSahrePtr<FJsonObject>)将输入流载体的Json数据反序列化到FJsonObject对象中,最后使用FJsonObject对象中的GetArrayField(FString)、GetBoolFiled(FString)、GetNumberField(FString)、GetStringField(FString)、GetObjectField(FString)、GetField(FString)等方法从Json对象中读取指定键的值。

蓝图节点:

 

  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
在 Unreal Engine 将字节数组转化为 JSON,可以使用 UE 提供的 FJson 模块。以下是一个简单的示例代码: ```c++ #include "JsonWriter.h" // 假设有一个 byte 数组叫做 jsonData,长度为 dataLen TSharedPtr<FJsonObject> JsonObject = MakeShareable(new FJsonObject); JsonObject->SetStringField("name", "Alice"); JsonObject->SetNumberField("age", 25); JsonObject->SetBoolField("isStudent", true); TArray<int32> Grades = {85, 92, 78}; TArray<TSharedPtr<FJsonValue>> JsonGrades; for (int32 i = 0; i < Grades.Num(); i++) { JsonGrades.Add(MakeShareable(new FJsonValueNumber(Grades[i]))); } JsonObject->SetArrayField("grades", JsonGrades); FString JsonString; TSharedRef<TJsonWriter<>> JsonWriter = TJsonWriterFactory<>::Create(&JsonString); FJsonSerializer::Serialize(JsonObject.ToSharedRef(), JsonWriter); // 现在 JsonString 就是转化后的 JSON 字符串 ``` 上述代码,首先创建一个 FJsonObject 对象,然后通过 FJsonObject 的各种 Set*Field 方法设置字段的值。其 grades 字段是一个数组,需要先创建一个 TArray<TSharedPtr<FJsonValue>> 对象,然后将每个元素转换为 TSharedPtr<FJsonValueNumber> 类型并添加到数组,最后通过 FJsonObject 的 SetArrayField 方法设置 grades 字段的值。 然后创建一个 TJsonWriter 对象,用于将 FJsonObject 对象转换为 JSON 字符串。最后调用 FJsonSerializer::Serialize 方法将 FJsonObject 对象序列化为 JSON 字符串,并存储在 FString 变量 JsonString 。 需要注意的是,在使用 FJson 模块生成 JSON 数据时,需要确保数据的格式正确,否则会导致生成的 JSON 数据不符合规范。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值