【UE4】UE4讀寫Json文件

一、準備工作

如果我們想要在UE4中讀寫Json文件,那麼我們必須使UE4包含Json和JsonUtilities這兩個模塊,那麼UE4如何添加模塊呢?

UE4添加預定義模塊的方法很簡單,我只需打開工程的.Biuld.cs文件,在其中的PublicDependencyModuleNames.AddRange()函數中追加兩個模塊即可,如:

using UnrealBuildTool;

public class DATA_sys : ModuleRules
{
	public DATA_sys(ReadOnlyTargetRules Target) : base(Target)
	{
		PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
	
		PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore" ,"Json","JsonUtilities"});

		PrivateDependencyModuleNames.AddRange(new string[] {  });

		// Uncomment if you are using Slate UI
		// PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" });
		
		// Uncomment if you are using online features
		// PrivateDependencyModuleNames.Add("OnlineSubsystem");

		// To include OnlineSubsystemSteam, add it to the plugins section in your uproject file with the Enabled attribute set to true
	}
}

如果我們要添加自定義模塊就有點麻煩了,當然這裏就不贅述了。

包含這兩個模塊之後,我們還需要用到 Json.h、JsonObject.h、JsonSerializer.h三個頭文件,其中JsonSerializer.h是用於Json序列化與反序列化用的。

至此我們就可以使用UE4自帶的工具進行Json文件的讀寫工作了。

二、Json文件寫

1.非序列化寫入

void AMysqlJsonCpp::CreatJson()
{
	FString filePath = FPaths::GameContentDir() + TEXT("MysqlConfig/Connect.json");
	FString jsonStr;
	TSharedRef<TJsonWriter<>> jsonWriter = TJsonWriterFactory<>::Create(&jsonStr);
	jsonWriter->WriteObjectStart();
	jsonWriter->WriteValue(TEXT("server"), TEXT("127.0.0.1"));
	jsonWriter->WriteObjectEnd();
	jsonWriter->Close();
	FFileHelper::SaveStringToFile(jsonStr, *filePath);
}
  • FPaths::GameContentDir()返回當前工程目錄的Content文件夾的路徑,FPaths爲UE4的路徑讀寫工具;

  • FString jsonStr的作用是用於關聯UE4的Json寫工具TJsonWriter<>,作爲輸入流載體,且JsonStr必須是FString類型;

  • TShareRef<T>是UE4自身的共享指針類型;

  • 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;

  • FFileHelperUE4的文件讀寫工具,方法SaveStringToFile(TJsonWriter*,FString*)函數的作用就是將Json寫工具中的Json數據寫到FString字符串中的路徑文件中。

使用非序列化方式寫入Json時,寫入方式需要嚴格按照Json的語法格式來做,如最開始需要使用WriterObjectStart()創建一個根前括號,即Json語法中最外面一層的{,所有寫入結束後需要使用WriterObjectEnd()聲明根對象結束,即Json語法中的最外面一層的},同理數組也需要按對象一樣的方法進行處理。如此才能寫入一個結構完整的Json文本。

2.序列化寫入

void AMyActor::Test()
{
	TSharedPtr<FJsonObject> rootObj = MakeShareable(new FJsonObject());
	rootObj->SetStringField("root", "1");
	TArray<TSharedPtr<FJsonValue>> arrValue;
	TSharedPtr<FJsonValueString> tmp = MakeShareable(new FJsonValueString("array"));
	arrValue.Add(tmp);
	rootObj->SetArrayField("array", arrValue);
	FString filePath = FPaths::GameContentDir() + TEXT("MysqlConfig/text.json");
	FString jsonStr;
	TSharedRef<TJsonWriter<TCHAR>> jsonWriter = TJsonWriterFactory<TCHAR>::Create(&jsonStr);
	FJsonSerializer::Serialize(rootObj.ToSharedRef(), jsonWriter);
	FFileHelper::SaveStringToFile(jsonStr, *filePath);
	UE_LOG(LogTemp, Error, TEXT("%s"),*filePath);
}

序列化的寫入方式則無需考慮按Json的語法結構進行寫入,序列化的寫入方式是通過一個FJsonObject對象進行Json文本的寫入。

  • 首先使用MakeSahreable()函數創建一個FJsonObject對象並使用共享指針引用。
  • 然後我們便可以使用FJsonObject對象中的SetArrayField(FString,TArray<FSharePtr<FJsonValue>>)SetBoolFiled(FString,bool)SetNumberField(FString,Number)SetStringField(FString,FString)SetObjectField(FString,TSharePtr<FJsonObject>)SetField(FString,TSharePtr<FJsonValue>)等函數向FJsonObject對象中寫分別入數組、bool值、數字、字符串、對象和Json鍵值對。其中數組的寫入較爲麻煩,我們需要先向創建Json鍵值對類型共享指針的TArray數組TArray<TSharePtr<FJsonValue>>。並向數組中添加指向FJsonValue對象的共享指針後然後纔可以使用SetArrayField進行數組的Json文本寫入。
  • 我們序列化寫好的FJsonObject對象需要轉化爲FString字符串才能向文本中寫入數據,FJsonObject轉化爲FString輸入流的方式就是FJsonSerializer::Serialize(TSharePtr<FJsonObject>.ToShareRef(),TSharePtr<FJsonWriter>);其中TSharePtr<FJsonWriter>和非序列化寫入一樣需要綁定一個FString作爲輸入流載體。
  • 最後就可以通過FFileHelper::SaveStringToFile(FString,*FString),前一個FString是輸入流載體,後一個*FString是Json文件的存儲路徑。

三、Json文件讀

1.反序列化讀取

TArray<FName> AMysqlJsonCpp::ReadMysqlConnectConfig()
{
	FString filePath = FPaths::GameContentDir() + TEXT("MysqlConfig/Connect.json");
	if (FPaths::FileExists(filePath))
	{
		FString server;
		FString dbName;
		FString userId;
		FString passwd;
		TArray<FName> connectConfig;
		FString fileStr;
		FFileHelper::LoadFileToString(fileStr, *filePath);
		TSharedPtr<FJsonObject> rootObject = MakeShareable(new FJsonObject());
		TSharedRef<TJsonReader<>> jsonReader = TJsonReaderFactory<>::Create(fileStr);
		if (FJsonSerializer::Deserialize(jsonReader, rootObject))
		{
			server = rootObject->GetStringField("server");
			dbName = rootObject->GetStringField("dbName");
			userId = rootObject->GetStringField("userId");
			passwd = rootObject->GetStringField("passwd");
		}
		connectConfig.Add(FName(*server));
		connectConfig.Add(FName(*dbName));
		connectConfig.Add(FName(*userId));
		connectConfig.Add(FName(*passwd));
	}

	return TArray<FName>();
}

  • 首先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對象中讀取指定鍵的值了。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章