UE 文件夹和文件操作
前言
UE有很多针对多平台的操作,其中文件操作也属于跨平台有差异的操作,UE4将跨平台文件封装在FPlatformFileManager::Get().GetPlatformFile()之中
操作示例
如果没有耐心看细节,只想搬砖就看这里吧
以我的工程myproject为例
image.png
//当前exe文件所在目录,所有其他路径都是相对这个路径计算的,也就是这个是当前工作路径
FPlatformProcess::BaseDir()
//打包工程的最外层
FPaths::RootDir()
//打包的文件下以工程名命名的文件夹
FPaths::GameDir()
//打包的引擎目录
FPaths::EngineDir()
//工程目录
FPaths::ProjectDir();//E:\ue\MyProject
//工程所在目录
FPaths::ProjectDir()
//加载目录
FPaths::LaunchDir()
//获取文件所在的路径
FPaths::GetPath(const FString& InPath)
//获取文件的名称,不带后缀
FPaths::GetBaseFilename(const FString& InPath, bool bRemovePath)
//获取文件的后缀
FPaths::GetExtension( const FString& InPath, bool bIncludeDot )
//在可执行文件目录新建一个文件目录
void CreateFolder(FString Path)
{
Path= FPaths::GameDir() / *Path;
Path= FPaths::ConvertRelativePathToFull(*Path);
FPlatformFileManager::Get().GetPlatformFile().CreateDirectoryTree(*Path);
}
//创建一个目录,路径参数位绝对路径
void CreateFolder(FString Path)
{
FPlatformFileManager::Get().GetPlatformFile().CreateDirectoryTree(*Path);
}
//删除一个可执行文件下的目录
void DeleteFolder(FString Path)
{
Path= FPaths::GameDir() / *Path;
Path= FPaths::ConvertRelativePathToFull(*Path);
FPlatformFileManager::Get().Get().GetPlatformFile().DeleteDirectoryRecursively(*Path);
}
//相应的,删除绝对路径的目录
void DeleteFolder(FString Path)
{
FPlatformFileManager::Get().Get().GetPlatformFile().DeleteDirectoryRecursively(*Path);
}
//获取某一目录下的所有文件
GetFolderFiles(TArray<FString> &Files,FString Path)
{
FPaths::NormalizeDirectoryName(Path);
IFileManager& FileManager = IFileManager::Get();
FString FinalPath = Path/ TEXT("*");
FileManager.FindFiles(Files, *FinalPath, true, true);
}
//文件夹是否存在
FPlatformFileManager::Get().GetPlatformFile().DirectoryExists(*Path)
//或
FPaths::DirectoryExists(Path)
//保存字符串
FString Date= FString("Test\n");
FString FilePath = FString("./SaveDate.txt");
FFileHelper::SaveStringToFile(Date, *FilePath);
//读取字符串
FString Date;
FString FilePath = FString("E:/SaveDate.txt");
FFileHelper::LoadFileToString(Date, *FilePath);
//保存字符串数组
TArray<FString> DateArray;
FString FilePath = FString("E:/SaveDate.txt");
FFileHelper::SaveStringToFile(DateArray, *FilePath);
//读取字符串数组
TArray<FString> DateArray;
FString FilePath = FString("E:/SaveDate.txt");
FFileHelper::LoadFileToString(DateArray, *FilePath);
Ue4的文件夹操作
先来个常规四件套
增加
CreateDirectoryTree
/**
* Copy a file or a hierarchy of files (directory).
* @param DestinationDirectory Target path (either absolute or relative) to copy to - always a directory! (e.g. "/home/dest/").
* @param Source Source file (or directory) to copy (e.g. "/home/source/stuff").
* @param bOverwriteAllExisting Whether to overwrite everything that exists at target
* @return true if operation completed successfully.
*/
virtual bool CopyDirectoryTree(const TCHAR* DestinationDirectory, const TCHAR* Source, bool bOverwriteAllExisting);
FPlatformFileManager::Get().GetPlatformFile().CreateDirectoryTree通过调用InternalCreateDirectoryTree,递归的创建所有的目录,就是说,即使父目录不存在,也会生成相应的目录。
CreateDirectory
这个函数在IPlatformFile中没有实现,是由具体的平台子类实现的,也就是说这个函数才是真的创建目录的函数,这个函数在父目录不存在的时候,会返回false。
通过拷贝增加文件夹CopyDirectoryTree
/**
- Copy a file or a hierarchy of files (directory).
- @param DestinationDirectory Target path (either absolute or relative) to copy to - always a directory! (e.g. “/home/dest/”).
- @param Source Source file (or directory) to copy (e.g. “/home/source/stuff”).
- @param bOverwriteAllExisting Whether to overwrite everything that exists at target
- @return true if operation completed successfully.
/
virtual bool CopyDirectoryTree(const TCHAR DestinationDirectory, const TCHAR* Source, bool bOverwriteAllExisting);
删除
DeleteDirectoryRecursively
/**
* Delete all files and subdirectories in a directory, then delete the directory itself
* @param Directory The directory to delete.
* @return true if the directory was deleted or did not exist.
**/
virtual bool DeleteDirectoryRecursively(const TCHAR* Directory);
DeleteDirectoryRecursively通过FDirectoryVisitor,使用迭代器访问文件夹,然后将文件夹中的文件和文件夹全部删除,这个操作是CreateDirectoryTree的逆操作,不同点在于这个操作同时处理了文件。
这个操作执行之后会自己检查刚才删除的文件夹是否还在,如果不在的话,返回成功,否则返回失败。
DeleteDirectory
对应于CreateDirectory,也没有实现,是由具体的平台子类实现的,同样在删除失败之后会报错。
修改
查找
IterateDirectory
/**
* Call the Visit function of the visitor once for each file or directory in a single directory. This function does not explore subdirectories.
* @param Directory The directory to iterate the contents of.
* @param Visitor Visitor to call for each element of the directory
* @return false if the directory did not exist or if the visitor returned false.
**/
virtual bool IterateDirectory(const TCHAR* Directory, FDirectoryVisitor& Visitor) = 0;
UE4定义了IterateDirectory,这个函数由两个参数,一个是路径,一个是对便利到的路径做操作的Visitor,这个Visitor同样是只有一个接口,具体实现可以自己写。通过Visitor 和IterateDirectory的相互调用实现了递归操作目录的目的。
IterateDirectoryRecursively
/**
* Call the Visit function of the visitor once for each file or directory in a directory tree. This function explores subdirectories.
* @param Directory The directory to iterate the contents of, recursively.
* @param Visitor Visitor to call for each element of the directory and each element of all subdirectories.
* @return false if the directory did not exist or if the visitor returned false.
**/
virtual bool IterateDirectoryRecursively(const TCHAR* Directory, FDirectoryVisitor& Visitor);
IterateDirectoryRecursively遍历文件夹的所有子文件夹,并且通过parallelfor加快了访问速度,在访问中对访问进行写锁定,并通过底层机制是否线程安全选择是否多线程执行,是很不错的便利文件夹的操作,同时这个访问也要求重写访问到指定目录之后需要做的操作,这里只需要执行具体操作就可以了。
文件存在性检测DirectoryExists
这个操作也是由平台子类实现,进行文件存在性检测,如果不存在就返回false
文件操作
增加
通过拷贝增加文件CopyFile
/**
* Copy a file. This will fail if the destination file already exists.
* @param To File to copy to.
* @param From File to copy from.
* @param ReadFlags Source file read options.
* @param WriteFlags Destination file write options.
* @return true if the file was copied sucessfully.
**/
virtual bool CopyFile(const TCHAR* To, const TCHAR* From, EPlatformFileRead ReadFlags = EPlatformFileRead::None, EPlatformFileWrite WriteFlags = EPlatformFileWrite::None);
拷贝文件到指定路径,如果拷贝失败或者目标路径有同名文件,会返回失败
删除
DeleteFile
删除指定的文件,具体实现由平台子类实现
修改
检查是否可以修改IsReadOnly
通过IsReadOnly检查文件是否可以修改,具体实现由平台子类实现
设置是否可以修改SetReadOnly
通过SetReadOnly设置文件是否可以被修改,具体实现由平台子类实现
移动文件位置或者修改文件名称MoveFile
通过MoveFile可以移动文件,如果源路径和目标路径的目录相同,就是修改文件名称了
读取文件类容 OpenRead
/** Attempt to open a file for reading.
*
* @param Filename file to be opened
* @param bAllowWrite (applies to certain platforms only) whether this file is allowed to be written to by other processes. This flag is needed to open files that are currently being written to as well.
*
* @return If successful will return a non-nullptr pointer. Close the file by delete'ing the handle.
*/
virtual IFileHandle* OpenRead(const TCHAR* Filename, bool bAllowWrite = false) = ```
**写入文件OpenWrite**
/** Attempt to open a file for writing. If successful will return a non-nullptr pointer. Close the file by delete'ing the handle. /
virtual IFileHandle OpenWrite(const TCHAR Filename, bool bAppend = false, bool bAllowRead = false) = 0;
**文件的二进制操作IFileHandle**
上面的OpenWrite和OpenRead两个都只是打开了文件,这两个方法返回的IFileHandle才是真正操作文件的,IFileHandle会以文件指针的方式处理文件的类容。
##查找
**FindFiles**
/**
* Finds all the files within the given directory, with optional file extension filter
* @param Directory The directory to iterate the contents of
* @param FileExtension If FileExtension is NULL, or an empty string "" then all files are found.
* Otherwise FileExtension can be of the form .EXT or just EXT and only files with that extension will be returned.
* @return FoundFiles All the files that matched the optional FileExtension filter, or all files if none was specified.
/
virtual void FindFiles(TArray<FString>& FoundFiles, const TCHAR Directory, const TCHAR* FileExtension);
FindFiles 通过给定的目录名称,获取目录下文件,可以指定文件的后缀进行筛选,这个方法只能获取到当前目录下的文件,不能进行递归搜索。
**FindFilesRecursively**
/**
* Finds all the files within the directory tree, with optional file extension filter
* @param Directory The starting directory to iterate the contents. This function explores subdirectories
* @param FileExtension If FileExtension is NULL, or an empty string "" then all files are found.
* Otherwise FileExtension can be of the form .EXT or just EXT and only files with that extension will be returned.
* @return FoundFiles All the files that matched the optional FileExtension filter, or all files if none was specified.
/
virtual void FindFilesRecursively(TArray<FString>& FoundFiles, const TCHAR Directory, const TCHAR* FileExtension);
FindFilesRecursively通过给定的目录名称,递归的获取目录下文件,可以指定文件的后缀进行筛选
文件查找的功能实际是通过FFindFilesVisitor加上文件夹查找的操作实现的
**文件存在性检查FileExists**
这个操作也是由平台子类实现,进行文件存在性检测,如果不存在就返回false
原文链接:https://blog.csdn.net/u012505629/article/details/118523590