大家好,我是阿赵。
这次学习一下在UE里面使用C++的API操作文件读写和文件夹操作。
一、UE引擎获取相关路径
获取到路径一般是相对路径,使用FPaths::ConvertRelativePathToFull转换后,可以获得完整的绝对路径。
FString contentDir = FPaths::ProjectContentDir();
UE_LOG(LogTemp,Display,TEXT("contentDir:%s"),*contentDir);
FString contentDirFull = FPaths::ConvertRelativePathToFull(contentDir);
UE_LOG(LogTemp, Display, TEXT("contentDirFull:%s"), *contentDirFull);
FString projectDir = FPaths::ProjectDir();
UE_LOG(LogTemp, Display, TEXT("projectDir:%s"), *projectDir);
FString projectDirFull = FPaths::ConvertRelativePathToFull(projectDir);
UE_LOG(LogTemp, Display, TEXT("projectDirFull:%s"), *projectDirFull);
FString gameSourceDir = FPaths::GameSourceDir();
UE_LOG(LogTemp, Display, TEXT("gameSourceDir:%s"), *gameSourceDir);
FString gameSourceDirFull = FPaths::ConvertRelativePathToFull(gameSourceDir);
UE_LOG(LogTemp, Display, TEXT("gameSourceDirFull:%s"), *gameSourceDirFull);
FString gameSaveDir = FPaths::ProjectSavedDir();
UE_LOG(LogTemp, Display, TEXT("gameSaveDir:%s"), *gameSaveDir);
FString gameSaveDirFull = FPaths::ConvertRelativePathToFull(gameSaveDir);
UE_LOG(LogTemp, Display, TEXT("gameSaveDirFull:%s"), *gameSaveDirFull);
FString logDir = FPaths::ProjectLogDir();
UE_LOG(LogTemp, Display, TEXT("logDir:%s"), *logDir);
FString logDirFull = FPaths::ConvertRelativePathToFull(logDir);
UE_LOG(LogTemp, Display, TEXT("logDirFull:%s"), *logDirFull);
FString sandboxDir = FPaths::SandboxesDir();
UE_LOG(LogTemp, Display, TEXT("sandboxDir:%s"), *sandboxDir);
FString sandboxDirFull = FPaths::ConvertRelativePathToFull(sandboxDir);
UE_LOG(LogTemp, Display, TEXT("sandboxDirFull:%s"), *sandboxDirFull);
FString contentDirSandbox = FPaths::ConvertToSandboxPath("testPackage", TEXT("azhao"));
UE_LOG(LogTemp, Display, TEXT("contentDirSandbox:%s"), *contentDirSandbox);
FString contentDirSandboxFull = FPaths::ConvertRelativePathToFull(contentDirSandbox);
UE_LOG(LogTemp, Display, TEXT("contentDirSandboxFull:%s"), *contentDirSandboxFull);
FString contentDirNormal = FPaths::ConvertFromSandboxPath(contentDirSandbox, TEXT("azhao"));
UE_LOG(LogTemp, Display, TEXT("contentDirNormal:%s"), *contentDirNormal);
FString testNormalPath = FPaths::ConvertToSandboxPath(contentDirNormal, TEXT("azhao"));
UE_LOG(LogTemp, Display, TEXT("testNormalPath:%s"), *testNormalPath);
FString internalDir = FPaths::ProjectIntermediateDir();
UE_LOG(LogTemp, Display, TEXT("internalDir:%s"), *internalDir);
FString internalDirFull = FPaths::ConvertRelativePathToFull(internalDir);
UE_LOG(LogTemp, Display, TEXT("internalDirFull:%s"), *internalDirFull);
FString platformDir = FPaths::ProjectPlatformExtensionsDir();
UE_LOG(LogTemp, Display, TEXT("platformDir:%s"), *platformDir);
FString platformDirFull = FPaths::ConvertRelativePathToFull(platformDir);
UE_LOG(LogTemp, Display, TEXT("platformDirFull:%s"), *platformDirFull);
打印结果如下:
LogTemp: Display:
contentDir:…/…/…/…/…/…/UETest/UECPPTest/Content/ LogTemp:
Display: contentDirFull:G:/UETest/UECPPTest/Content/ LogTemp: Display:
projectDir:…/…/…/…/…/…/UETest/UECPPTest/ LogTemp: Display:
projectDirFull:G:/UETest/UECPPTest/ LogTemp: Display:
gameSourceDir:…/…/…/…/…/…/UETest/UECPPTest/Source/ LogTemp:
Display: gameSourceDirFull:G:/UETest/UECPPTest/Source/ LogTemp:
Display: gameSaveDir:…/…/…/…/…/…/UETest/UECPPTest/Saved/
LogTemp: Display: gameSaveDirFull:G:/UETest/UECPPTest/Saved/ LogTemp:
Display: logDir:…/…/…/…/…/…/UETest/UECPPTest/Saved/Logs/
LogTemp: Display: logDirFull:G:/UETest/UECPPTest/Saved/Logs/ LogTemp:
Display: sandboxDir:…/…/…/…/…/…/UETest/UECPPTest/Saved/Sandboxes
LogTemp: Display: sandboxDirFull:G:/UETest/UECPPTest/Saved/Sandboxes
LogTemp: Display:
contentDirSandbox:…/…/…/…/…/…/UETest/UECPPTest/Saved/Sandboxes/azhaoEngine/Binaries/Win64/testPackage
LogTemp: Display:
contentDirSandboxFull:G:/UETest/UECPPTest/Saved/Sandboxes/azhaoEngine/Binaries/Win64/testPackage
LogTemp: Display: contentDirNormal:G:/Program Files/Epic
Games/UE_5.3/Engine/Binaries/Win64/testPackage LogTemp: Display:
testNormalPath:…/…/…/…/…/…/UETest/UECPPTest/Saved/Sandboxes/azhaoEngine/Binaries/Win64/testPackage
LogTemp: Display:
internalDir:…/…/…/…/…/…/UETest/UECPPTest/Intermediate/ LogTemp:
Display: internalDirFull:G:/UETest/UECPPTest/Intermediate/ LogTemp:
Display: platformDir:…/…/…/…/…/…/UETest/UECPPTest/Platforms/
LogTemp: Display: platformDirFull:G:/UETest/UECPPTest/Platforms/
二、文件和文件夹操作
涉及到文件夹和文件操作的API有多个,主要是集中在FPaths和FFileHelper这两个类。我自己封装了一个文件操作的工具类,叫做MyFileManager,应该囊括了大部分的文件夹和文件的操作了。
MyFileManager.h
#pragma once
#include "CoreMinimal.h"
/**
*
*/
class UECPPTEST_API MyFileManager
{
public:
MyFileManager();
~MyFileManager();
/// <summary>
/// 获取文件字节大小,如果文件不存在返回-1
/// </summary>
/// <param name="path">文件路径</param>
/// <returns></returns>
static int64 GetFileSize(FString path);
/// <summary>
/// 判断文件夹是否存在
/// </summary>
/// <param name="path">文件夹路径</param>
/// <returns></returns>
static bool IsDirExist(FString path);
/// <summary>
/// 检查保存文件的路径是否存在,如果不存在就自动创建
/// </summary>
/// <param name="path">保存文件的路径</param>
static void CheckFileSavePath(FString path);
/// <summary>
/// 检查文件夹是否存在,如果不存在就自动创建
/// </summary>
/// <param name="path">文件夹路径</param>
static void CheckDirection(FString path);
/// <summary>
/// 创建文件夹
/// </summary>
/// <param name="path">文件夹路径</param>
/// <returns></returns>
static bool CreateFolder(FString path);
/// <summary>
/// 判断文件是否存在
/// </summary>
/// <param name="path">文件路径</param>
/// <returns></returns>
static bool IsFileExist(FString path);
/// <summary>
/// 保存字符串到文件
/// </summary>
/// <param name="path">保存路径</param>
/// <param name="content">保存内容</param>
static void SaveFile(FString path, FString content);
/// <summary>
/// 指定编码保存字符串到文件
/// </summary>
/// <param name="path">保存路径</param>
/// <param name="content">保存内容</param>
/// <param name="code">编码</param>
static void SaveFileByCode(FString path, FString content, FFileHelper::EEncodingOptions code);
/// <summary>
/// 追加字符串到指定文件
/// </summary>
/// <param name="path">文件路径</param>
/// <param name="content">追加内容</param>
static void SaveFileAppend(FString path, FString content);
/// <summary>
/// 指定编码追加字符串到文件
/// </summary>
/// <param name="path">文件路径</param>
/// <param name="content">追加内容</param>
/// <param name="code">指定编码</param>
static void SaveFileAppendByCode(FString path, FString content, FFileHelper::EEncodingOptions code);
/// <summary>
/// 保存多行字符串到指定文件
/// </summary>
/// <param name="path">文件路径</param>
/// <param name="lines">多行内容</param>
/// <param name="isAppend">是否追加</param>
static void SaveFileAllLines(FString path, TArray<FString> lines, bool isAppend = true);
/// <summary>
/// 指定编码保存多行字符串到指定文件
/// </summary>
/// <param name="path">文件路径</param>
/// <param name="lines">多行内容</param>
/// <param name="code">指定编码</param>
/// <param name="isAppend">是否追加</param>
static void SaveFileAllLinesByCode(FString path, TArray<FString> lines, FFileHelper::EEncodingOptions code, bool isAppend = true);
/// <summary>
/// 保存字节到文件
/// </summary>
/// <param name="path">文件路径</param>
/// <param name="bytes">需要保存的字节</param>
static void SaveBytes(FString path, TArray<uint8> bytes);
/// <summary>
/// 删除文件夹
/// </summary>
/// <param name="path">文件夹路径</param>
static void DelFolder(FString path);
/// <summary>
/// 删除文件
/// </summary>
/// <param name="path">文件路径</param>
static void DelFile(FString path);
/// <summary>
/// 读取所有行
/// </summary>
/// <param name="path">文件路径</param>
static TArray<FString> ReadAllLines(FString path);
/// <summary>
/// 读取文件字符串
/// </summary>
/// <param name="path">文件路径</param>
/// <returns></returns>
static FString ReadFileText(FString path);
/// <summary>
/// 读取文件bytes
/// </summary>
/// <param name="path">文件路径</param>
/// <returns></returns>
static TArray<uint8> ReadFileBytes(FString path);
/// <summary>
/// 获取文件夹下指定后缀的所有文件路径
/// </summary>
static TArray<FString> GetAllFiles(FString path, FString exName);
/// <summary>
/// 获取文件夹下除了指定后缀名以外的所有文件路径
/// </summary>
static TArray<FString> GetAllFilesExcept(FString path, FString exName);
/// <summary>
/// 获取某文件夹下的第一层子文件夹路径
/// </summary>
static TArray<FString> GetSubFolders(FString path);
/// <summary>
/// 获取某文件夹下的所有子文件夹路径
/// </summary>
static TArray<FString> GetSubFoldersAll(FString path);
/// <summary>
/// 获取某文件夹下第一层的子文件路径
/// </summary>
static TArray<FString> GetSubFiles(FString path, FString exName);
/// <summary>
/// 拷贝文件
/// </summary>
static void CopyFile(FString fromPath, FString toPath);
/// <summary>
/// 复制文件夹
/// </summary>
static void CopyFolder(FString fromPath, FString toPath);
/// <summary>
/// 移动文件夹
/// </summary>
static void MoveFolder(FString fromPath, FString toPath);
/// <summary>
/// 移动文件
/// </summary>
static void MoveFile(FString fromPath, FString toPath);
/// <summary>
/// 复制文件夹内指定扩展名的文件
/// </summary>
/// <param name="fromPath"></param>
/// <param name="toPath"></param>
/// <param name="exName"></param>
static void CopyFolderByExName(FString fromPath, FString toPath, FString exName);
/// <summary>
/// 复制文件夹内除了指定扩展名的文件
/// </summary>
static void CopyFolderByExceptExName(FString fromPath, FString toPath, FString exName);
/// <summary>
/// 获取扩展名
/// </summary>
/// <param name="fileName">文件名</param>
/// <returns></returns>
static FString GetExName(FString fileName);
/// <summary>
/// 去除扩展名
/// </summary>
/// <param name="fileName">文件名</param>
/// <returns></returns>
static FString RemoveExName(FString fileName);
};
MyFileManager.cpp
#include "Tools/MyFileManager.h"
MyFileManager::MyFileManager()
{
}
MyFileManager::~MyFileManager()
{
}
int64 MyFileManager::GetFileSize(FString path)
{
if (&path == nullptr)
{
return -1;
}
FFileStatData fileData = IFileManager::Get().GetStatData(*path);
return fileData.FileSize;
}
void MyFileManager::CheckFileSavePath(FString path)
{
FString folderPath = FPaths::GetPath(path);
MyFileManager::CheckDirection(folderPath);
}
bool MyFileManager::IsDirExist(FString path)
{
bool isExist = FPaths::DirectoryExists(path);
return isExist;
}
void MyFileManager::CheckDirection(FString path)
{
bool isExist = FPaths::DirectoryExists(path);
if (isExist == false)
{
MyFileManager::CreateFolder(path);
}
}
bool MyFileManager::CreateFolder(FString path)
{
bool isExist = FPaths::DirectoryExists(path);
if (isExist == true)
{
return true;
}
FString PathStr = path;
if (!PathStr.EndsWith("/") && !PathStr.EndsWith("\\"))
{
PathStr += "/"; // Ensure the path ends with a slash
}
FPlatformFileManager::Get().GetPlatformFile().CreateDirectoryTree(*PathStr);
return FPaths::DirectoryExists(path);
}
bool MyFileManager::IsFileExist(FString path)
{
bool isExist = FPaths::FileExists(path);
return isExist;
}
void MyFileManager::SaveFile(FString path, FString content)
{
MyFileManager::CheckFileSavePath(path);
FFileHelper::SaveStringToFile(content, *path, FFileHelper::EEncodingOptions::ForceUTF8WithoutBOM);
}
void MyFileManager::SaveFileByCode(FString path, FString content, FFileHelper::EEncodingOptions code)
{
MyFileManager::CheckFileSavePath(path);
FFileHelper::SaveStringToFile(content, *path, code);
}
void MyFileManager::SaveFileAppend(FString path, FString content)
{
MyFileManager::CheckFileSavePath(path);
FFileHelper::SaveStringToFile(content, *path, FFileHelper::EEncodingOptions::ForceUTF8WithoutBOM, &IFileManager::Get(), EFileWrite::FILEWRITE_Append);
}
void MyFileManager::SaveFileAppendByCode(FString path, FString content, FFileHelper::EEncodingOptions code)
{
MyFileManager::CheckFileSavePath(path);
FFileHelper::SaveStringToFile(content, *path,code, &IFileManager::Get(), EFileWrite::FILEWRITE_Append);
}
void MyFileManager::SaveFileAllLines(FString path, TArray<FString> lines, bool isAppend)
{
MyFileManager::CheckFileSavePath(path);
if (isAppend == false)
{
FFileHelper::SaveStringArrayToFile(lines, *path, FFileHelper::EEncodingOptions::ForceUTF8WithoutBOM);
}
else
{
FFileHelper::SaveStringArrayToFile(lines, *path, FFileHelper::EEncodingOptions::ForceUTF8WithoutBOM,&IFileManager::Get(),EFileWrite::FILEWRITE_Append);
}
}
void MyFileManager::SaveFileAllLinesByCode(FString path, TArray<FString> lines, FFileHelper::EEncodingOptions code, bool isAppend)
{
MyFileManager::CheckFileSavePath(path);
if (isAppend == false)
{
FFileHelper::SaveStringArrayToFile(lines, *path, code);
}
else
{
FFileHelper::SaveStringArrayToFile(lines, *path, code, &IFileManager::Get(), EFileWrite::FILEWRITE_Append);
}
}
void MyFileManager::SaveBytes(FString path, TArray<uint8> bytes)
{
MyFileManager::CheckFileSavePath(path);
FFileHelper::SaveArrayToFile(bytes, *path);
}
void MyFileManager::DelFolder(FString path)
{
FString PathStr = path;
if (!PathStr.EndsWith("/") && !PathStr.EndsWith("\\"))
{
PathStr += "/"; // Ensure the path ends with a slash
}
FPlatformFileManager::Get().GetPlatformFile().DeleteDirectoryRecursively(*PathStr);
}
void MyFileManager::DelFile(FString path)
{
FPlatformFileManager::Get().GetPlatformFile().DeleteFile(*path);
}
TArray<FString> MyFileManager::ReadAllLines(FString path)
{
TArray<FString> textData;
FFileHelper::LoadFileToStringArray(textData, *path);
return textData;
}
FString MyFileManager::ReadFileText(FString path)
{
FString result;
FFileHelper::LoadFileToString(result, *path);
return result;
}
TArray<uint8> MyFileManager::ReadFileBytes(FString path)
{
TArray<uint8> result;
FFileHelper::LoadFileToArray(result, *path);
return result;
}
TArray<FString> MyFileManager::GetAllFiles(FString path, FString exName)
{
TArray<FString> result;
if (IsDirExist(path) == false)
{
return result;
}
exName = exName.ToLower();
FString PathStr = path;
if (!PathStr.EndsWith("/") && !PathStr.EndsWith("\\"))
{
PathStr += "/"; // Ensure the path ends with a slash
}
FPlatformFileManager::Get().GetPlatformFile().FindFilesRecursively(result, *PathStr,*exName);
return result;
}
TArray<FString> MyFileManager::GetAllFilesExcept(FString path, FString exName)
{
TArray<FString> allFiles = MyFileManager::GetAllFiles(path, "");
if (allFiles.Num() == 0)
{
return allFiles;
}
exName = exName.ToLower();
TArray<FString> result;
for (int i = 0; i < allFiles.Num(); i++)
{
FString ex = FPaths::GetExtension(allFiles[i]);
ex = ex.ToLower();
if (exName.Equals(ex) == false)
{
result.Add(allFiles[i]);
}
}
return result;
}
struct DirectoryVisitor : public IPlatformFile::FDirectoryVisitor
{
TArray<FString> dirNames;
TArray<FString> fileNames;
//This function is called for every file or directory it finds.
bool Visit(const TCHAR* FilenameOrDirectory, bool bIsDirectory) override
{
// did we find a Directory or a file?
if (bIsDirectory)
{
dirNames.Add(FilenameOrDirectory);
}
else
{
fileNames.Add(FilenameOrDirectory);
}
return true;
}
};
TArray<FString> MyFileManager::GetSubFolders(FString path)
{
FString PathStr = path;
if (!PathStr.EndsWith("/") && !PathStr.EndsWith("\\"))
{
PathStr += "/"; // Ensure the path ends with a slash
}
TArray<FString> result;
DirectoryVisitor visitor;
if (FPlatformFileManager::Get().GetPlatformFile().IterateDirectory(*PathStr, visitor))
{
result = visitor.dirNames;
}
return result;
}
TArray<FString> MyFileManager::GetSubFoldersAll(FString path)
{
FString PathStr = path;
if (!PathStr.EndsWith("/") && !PathStr.EndsWith("\\"))
{
PathStr += "/"; // Ensure the path ends with a slash
}
TArray<FString> result;
DirectoryVisitor visitor;
if (FPlatformFileManager::Get().GetPlatformFile().IterateDirectoryRecursively(*PathStr, visitor))
{
result = visitor.dirNames;
}
return result;
}
TArray<FString> MyFileManager::GetSubFiles(FString path,FString exName)
{
FString PathStr = path;
if (!PathStr.EndsWith("/") && !PathStr.EndsWith("\\"))
{
PathStr += "/"; // Ensure the path ends with a slash
}
TArray<FString> result;
FPlatformFileManager::Get().GetPlatformFile().FindFiles(result, *PathStr,*exName);
return result;
}
void MyFileManager::CopyFile(FString fromPath, FString toPath)
{
MyFileManager::CheckFileSavePath(toPath);
FPlatformFileManager::Get().GetPlatformFile().CopyFile(*toPath, *fromPath);
}
void MyFileManager::CopyFolder(FString fromPath, FString toPath)
{
FPlatformFileManager::Get().GetPlatformFile().CopyDirectoryTree(*toPath, *fromPath,true);
}
void MyFileManager::MoveFolder(FString fromPath, FString toPath)
{
bool isSuccess = FPlatformFileManager::Get().GetPlatformFile().CopyDirectoryTree(*toPath, *fromPath, true);
if (isSuccess == true)
{
MyFileManager::DelFolder(fromPath);
}
}
void MyFileManager::MoveFile(FString fromPath, FString toPath)
{
FPlatformFileManager::Get().GetPlatformFile().MoveFile(*toPath, *fromPath);
}
void MyFileManager::CopyFolderByExName(FString fromPath, FString toPath, FString exName)
{
TArray<FString> files = MyFileManager::GetAllFiles(*fromPath, exName);
if (files.Num() == 0)
{
return;
}
for (int i = 0; i < files.Num(); i++)
{
FString newPath = files[i].Replace(*fromPath, *toPath, ESearchCase::CaseSensitive);
MyFileManager::CopyFile(files[i], newPath);
}
}
void MyFileManager::CopyFolderByExceptExName(FString fromPath, FString toPath, FString exName)
{
TArray<FString> files = MyFileManager::GetAllFilesExcept(fromPath, exName);
if (files.Num() == 0)
{
return;
}
for (int i = 0; i < files.Num(); i++)
{
FString newPath = files[i].Replace(*fromPath, *toPath, ESearchCase::CaseSensitive);
MyFileManager::CopyFile(files[i], newPath);
}
}
FString MyFileManager::GetExName(FString fileName)
{
return FPaths::GetExtension(fileName);
}
FString MyFileManager::RemoveExName(FString fileName)
{
return FPaths::GetBaseFilename(fileName);
}
标签:阿赵,MyFileManager,C++,LogTemp,void,UE,path,Display,FString
From: https://blog.csdn.net/liweizhao/article/details/138589909