UE4中文本文件配置文件Json文件XML文件的讀寫

虛幻引擎中提供了與平臺無關的文件讀寫與訪問接口,通過調用,可以完成一些文件的讀寫。比如文本文件,配置文件,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對象中讀取指定鍵的值。

藍圖節點:

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章