File and Folder Management, Create, Find, Delete

From UE4: Community Wiki
Jump to: navigation, search


This article is a preliminary version, it is subject to change.


Introduction[edit]

If you want to handle files and folders in ue4, you need to use their file system. UFS(Unreal File System), Here I will show you how to use UFS to Manipulate the Files and folders itself. This means I won't show how to change the content of the Files. I will do this in another article.

First, We will take a look at how we can find the right path to your file or folder.—finding either a project path or an engine path.

Paths[edit]

One of the first things you need to do when dealing with files and folders is finding the right path. For commonly used UE4 folders, there is an excellent way to get to them.

Now let's get the project Directory and log it.

// Get the project directory and save it in ProjectDirectory
FString ProjectDirectory = FPaths::ProjectDir();
UE_LOG(LogTemp, Warning, TEXT("FilePaths: ProjectDirectory: %s"),*ProjectDirectory);

Great! This gets us.

LogTemp: Warning: FilePaths: ProjectDirectory: D:/Projects/UE4/UFS/

I can see that my project is located in D:/Projects/UE4/UFS/ This is correct.

Project related folders[edit]

Now there is a whole load of other folders lets take a look at them.

    FString ProjectDirectory = FPaths::ProjectDir();
	UE_LOG(LogTemp, Warning, TEXT("FilePaths: ProjectDir: %s"),*ProjectDirectory);

	FString ProjectConfigDirectory = FPaths::ProjectConfigDir();
	UE_LOG(LogTemp, Warning, TEXT("FilePaths: ProjectConfigDir: %s"),*ProjectConfigDirectory);

	FString ProjectContentDirectory = FPaths::ProjectContentDir();
	UE_LOG(LogTemp, Warning, TEXT("FilePaths: ProjectContentDir: %s"),*ProjectContentDirectory);
	
	FString ProjectIntermediateDirectory = FPaths::ProjectIntermediateDir();
	UE_LOG(LogTemp, Warning, TEXT("FilePaths: ProjectIntermediateDirectory: %s"),*ProjectIntermediateDirectory);

	FString ProjectLogDirectory = FPaths::ProjectLogDir();
	UE_LOG(LogTemp, Warning, TEXT("FilePaths: ProjectLogDir: %s"),*ProjectLogDirectory);

	FString ProjectModsDirectory = FPaths::ProjectModsDir();
	UE_LOG(LogTemp, Warning, TEXT("FilePaths: ProjectModsDir: %s"),*ProjectModsDirectory);

	FString ProjectPluginsDirectory = FPaths::ProjectPluginsDir();
	UE_LOG(LogTemp, Warning, TEXT("FilePaths: ProjectPluginsDir: %s"),*ProjectPluginsDirectory);

	FString ProjectSavedDirectory = FPaths::ProjectSavedDir();
	UE_LOG(LogTemp, Warning, TEXT("FilePaths: ProjectSavedDir: %s"),*ProjectSavedDirectory);

	FString ProjectUserDirectory = FPaths::ProjectUserDir();
	UE_LOG(LogTemp, Warning, TEXT("FilePaths: ProjectUserDir: %s"),*ProjectUserDirectory);

	FString ProjectPersistentDownloadDirectory = FPaths::ProjectPersistentDownloadDir();
	UE_LOG(LogTemp, Warning, TEXT("FilePaths: ProjectPersistentDownloadDir: %s"),*ProjectPersistentDownloadDirectory);

	FString ProjectPlatformExtensionsDirectory = FPaths::ProjectPlatformExtensionsDir();
	UE_LOG(LogTemp, Warning, TEXT("FilePaths: ProjectPlatformExtensionsDir: %s"),*ProjectPlatformExtensionsDirectory);

Okey This gives me:

LogTemp: Warning: FilePaths: ProjectDir: D:/Projects/UE4/UFS/
LogTemp: Warning: FilePaths: ProjectConfigDir: D:/Projects/UE4/UFS/Config/
LogTemp: Warning: FilePaths: ProjectContentDir: D:/Projects/UE4/UFS/Content/
LogTemp: Warning: FilePaths: ProjectIntermediateDirectory: D:/Projects/UE4/UFS/Intermediate/
LogTemp: Warning: FilePaths: ProjectLogDir: D:/Projects/UE4/UFS/Saved/Logs/
LogTemp: Warning: FilePaths: ProjectModsDir: D:/Projects/UE4/UFS/Mods/
LogTemp: Warning: FilePaths: ProjectPluginsDir: D:/Projects/UE4/UFS/Plugins/
LogTemp: Warning: FilePaths: ProjectSavedDir: D:/Projects/UE4/UFS/Saved/
LogTemp: Warning: FilePaths: ProjectUserDir: D:/Projects/UE4/UFS/
LogTemp: Warning: FilePaths: ProjectPersistentDownloadDir: D:/Projects/UE4/UFS/PersistentDownloadDir
LogTemp: Warning: FilePaths: ProjectPlatformExtensionsDir: D:/Projects/UE4/UFS/Platforms/

In Unreal Engine 4 the paths are often stored in FString. But the UFS(Unreal File System) deals with TCHAR* So we need to be able to convert TString To TCHAR* We do this by adding a * in front of the variable


Engine related folders[edit]

Beside Project folders. You can also get engine folders.

    FString EngineDirectory = FPaths::EngineDir();
	UE_LOG(LogTemp, Warning, TEXT("FilePaths: EngineDir: %s"),*EngineDirectory);

	FString EngineConfigDirectory = FPaths::EngineConfigDir();
	UE_LOG(LogTemp, Warning, TEXT("FilePaths: EngineConfigDir: %s"),*EngineConfigDirectory);

	FString EngineContentDirectory = FPaths::EngineConfigDir();
	UE_LOG(LogTemp, Warning, TEXT("FilePaths: EngineContentDir: %s"),*EngineContentDirectory);
	
	FString EngineIntermediateDirectory = FPaths::EngineIntermediateDir();
	UE_LOG(LogTemp, Warning, TEXT("FilePaths: EngineIntermediateDirectory: %s"),*EngineIntermediateDirectory);

	FString EnginePluginsDirectory = FPaths::EnginePluginsDir();
	UE_LOG(LogTemp, Warning, TEXT("FilePaths: EnginePluginsDir: %s"),*EnginePluginsDirectory);

	FString EngineSavedDirectory = FPaths::EngineSavedDir();
	UE_LOG(LogTemp, Warning, TEXT("FilePaths: EngineSavedDir: %s"),*EngineSavedDirectory);

	FString EngineUserDirectory = FPaths::EngineUserDir();
	UE_LOG(LogTemp, Warning, TEXT("FilePaths: EngineUserDir: %s"),*EngineUserDirectory);

	FString EngineDefaultLayoutDir = FPaths::EngineDefaultLayoutDir();
	UE_LOG(LogTemp, Warning, TEXT("FilePaths: EngineDefaultLayoutDir: %s"),*EngineDefaultLayoutDir);

	FString EnginePlatformExtensionsDir = FPaths::EnginePlatformExtensionsDir();
	UE_LOG(LogTemp, Warning, TEXT("FilePaths: EnginePlatformExtensionsDir: %s"),*EnginePlatformExtensionsDir);

	FString EngineUserLayoutDir = FPaths::EngineUserLayoutDir();
	UE_LOG(LogTemp, Warning, TEXT("FilePaths: EngineUserLayoutDir: %s"),*EngineUserLayoutDir);

Okey This gives me:

LogTemp: Warning: FilePaths: EngineDir: ../../../Engine/
LogTemp: Warning: FilePaths: EngineConfigDir: ../../../Engine/Config/
LogTemp: Warning: FilePaths: EngineContentDir: ../../../Engine/Config/
LogTemp: Warning: FilePaths: EngineIntermediateDirectory: ../../../Engine/Intermediate/
LogTemp: Warning: FilePaths: EnginePluginsDir: ../../../Engine/Plugins/
LogTemp: Warning: FilePaths: EngineSavedDir: C:/Users/Rene/AppData/Local/UnrealEngine/4.25/Saved/
LogTemp: Warning: FilePaths: EngineUserDir: C:/Users/Rene/AppData/Local/UnrealEngine/4.25/
LogTemp: Warning: FilePaths: EngineDefaultLayoutDir: ../../../Engine/Config/Layouts/
LogTemp: Warning: FilePaths: EnginePlatformExtensionsDir: ../../../Engine/Platforms/
LogTemp: Warning: FilePaths: EngineUserLayoutDir: C:/Users/Rene/AppData/Local/UnrealEngine/4.25/Saved/Config/Layouts/

Okey We now have a way to get a path. Let's try to use it.

FPlatformFileManager, finding files and Directories[edit]

UFS(Unreal file system) is platform-agnostic Meaning it will work on every platform you build for. So as long as you use this, it will work for PC, Mac, Oculus, Android ext...

The first thing we need to do is to create an IPlatformFile& using FPlatformFileManager

IPlatformFile& FileManager = FPlatformFileManager::Get().GetPlatformFile();

Now we can use the FileManager to perform all kind of operations.

FPlatformFileManager


Does a directory Exist?[edit]

You often want to be safe and make sure a directory exists before you try to use it. We can do this using the function:
DirectoryExists(TCHAR*)
This will return a true or false. Here is an example function checking if a directory Exists:

    // Getting the directory we want to check if it exists
    FString MyConfigDirectory = FPaths::ProjectConfigDir();
	MyConfigDirectory.Append(TEXT("MyConfigDir"));
    // Creating the FileManager
	IPlatformFile& FileManager = FPlatformFileManager::Get().GetPlatformFile();
    /*This is where the magic happens.
    * The DirectoryExist function takes in one argument a TCHAR*
    * But since we have an FString we need to dereference it Using a *
    */
	if(FileManager.DirectoryExists(*MyConfigDirectory))
	{
		UE_LOG(LogTemp, Warning, TEXT("FilePaths: Directory Exists"));
	}
	else
	{
		UE_LOG(LogTemp, Warning, TEXT("FilePaths: Directory Does not exist"));
	}

In this case, the folder does not exist, so I get this in return.

LogTemp: Warning: FilePaths: Directory Does not exist


How do I create a directory?[edit]

In this case, we don't have a directory, so we need to create one We can do this using the function:
CreateDirectory(TChar*)
This function will return a true if the directory was created and false if it failed to create the directory. Here is an example of creating a directory.

    // Getting the directory we want to check if it exists
    FString MyConfigDirectory = FPaths::ProjectConfigDir();
	MyConfigDirectory.Append(TEXT("MyConfigDir"));
    // Creating the FileManager
	IPlatformFile& FileManager = FPlatformFileManager::Get().GetPlatformFile();
    /*This is where the magic happens.
    * The CreateDirectory function takes in one argument a TCHAR*
    * But since we have an FString we need to dereference it Using a *
    */
	if(FileManager.CreateDirectory(*MyConfigDirectory))
	{
		UE_LOG(LogTemp, Warning, TEXT("FilePaths: Directory was created"));
	}
	else
	{
		UE_LOG(LogTemp, Warning, TEXT("FilePaths: Directory was not created"));
	}

In this case, the directory is correctly created. And I get this in return

LogTemp: Warning: FilePaths: Directory was created


How do I create a directory tree[edit]

Some times you don't want to create one folder but a whole tree of folders. We can do this using the function:
CreateDirectoryTree(TChar*)
This will return a true if the directory was created and false if it failed to create the directory. Here is an example of creating a directory tree.

    // Getting the directory we want to check if it exists
    FString MyConfigDirectoryTree = FPaths::ProjectConfigDir();
	MyConfigDirectoryTree.Append(TEXT("MyConfigDir/SecondFolder/ThirdFolder"));
    // Creating the FileManager
	IPlatformFile& FileManager = FPlatformFileManager::Get().GetPlatformFile();
    /*This is where the magic happens.
    * The CreateDirectoryTree function takes in one argument a TCHAR*
    * But since we have an FString we need to dereference it Using a *
    */
	if(FileManager.CreateDirectoryTree(*MyConfigDirectoryTree))
	{
		UE_LOG(LogTemp, Warning, TEXT("FilePaths: DirectoryTree was created"));
	}
	else
	{
		UE_LOG(LogTemp, Warning, TEXT("FilePaths: Directory Was not Created"));
	}

In this case, the directory tree is created so I get this in return.

LogTemp: Warning: FilePaths: DirectoryTree was created


How do I Delete a directory?[edit]

In this case, We already have a directory, but we don't want it any more. We can do this using the function:
.DeleteDirectory(TChar*)
This will return a true if the directory was Deleted and false if it failed to Delete the directory. Here is an example of Deleting a directory.

    // Getting the directory we want to check if it exists
    FString MyConfigDirectory = FPaths::ProjectConfigDir();
	MyConfigDirectory.Append(TEXT("MyConfigDir"));
    // Creating the FileManager
	IPlatformFile& FileManager = FPlatformFileManager::Get().GetPlatformFile();
    /*This is where the magic happens.
    * The DeleteDirectory function takes in one argument a TCHAR*
    * But since we have an FString we need to dereference it Using a *
    */
	if(FileManager.DeleteDirectory(*MyConfigDirectory))
	{
		UE_LOG(LogTemp, Warning, TEXT("FilePaths: Directory was Deleted"));
	}
	else
	{
		UE_LOG(LogTemp, Warning, TEXT("FilePaths: Directory was not Deleted"));
	}

In this case, the directory is Deleted, so I get this in return.

LogTemp: Warning: FilePaths: Directory was Deleted

Some times this function fails. A reason for this might be that the folder contains a file.


How do I Delete a directory with files in it?[edit]

This will delete all files in the directory

If a directory has files in it, we can't just use the DeleteDirectory() function. In this case, we need to use the function:
.DeleteDirectoryRecursively(TCHAR*)
This function returns true if the directory and all its containing files and folders are Deleted and false if it failed to Delete the directory. Here is an example of Deleting a directory with all its sub-files and folders.

    // Getting the directory we want to check if it exists
    FString MyConfigDirectory = FPaths::ProjectConfigDir();
	MyConfigDirectory.Append(TEXT("MyConfigDir"));
    // Creating the FileManager
	IPlatformFile& FileManager = FPlatformFileManager::Get().GetPlatformFile();
    /*This is where the magic happens.
    * The DeleteDirectoryRecursively function takes in one argument a TCHAR*
    * But since we have an FString we need to dereference it Using a *
    */
	if(FileManager.DeleteDirectoryRecursively(*MyConfigDirectory))
	{
		UE_LOG(LogTemp, Warning, TEXT("FilePaths: Directory and sub-files and folders are Deleted"));
	}
	else
	{
		UE_LOG(LogTemp, Warning, TEXT("FilePaths: Directory and sub-files and folders are not Deleted"));
	}

In this case, the directory and its sub-files and folder are all deleted, and we get this return.

LogTemp: Warning: FilePaths: Directory was Deleted


How do I find all file's and folders in a directory[edit]

To do this is a bit more complicated and needs some extra coding. The base is still the same we ask the FileManager to do something, But it requires a little bit of additional setup. We need to create a Struct that inherits from IPlatformFile::FDirectoryVisitor And Overid

  struct DirectoryVisitor : public IPlatformFile::FDirectoryVisitor
{
	//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)
		{
			UE_LOG(LogTemp, Warning, TEXT("FilePaths: Directory found: %s"),FilenameOrDirectory);
		}
		else
		{
			UE_LOG(LogTemp, Warning, TEXT("FilePaths: File Found: %s"),FilenameOrDirectory);
		}
		return true;
	}
};

Now we have created the DirectoryVisitor struct we can use it in our code.

   FString MyConfigDirectoryTree = FPaths::ProjectConfigDir();
	MyConfigDirectoryTree.Append(TEXT("MyConfigDir"));
	IPlatformFile& FileManager = FPlatformFileManager::Get().GetPlatformFile();
    //Now we need to create a DirectoryVisitor 
	DirectoryVisitor Visitor;
    // The ItterateDirectory takes two arguments The directory and the Visitor we created above.
	if(FileManager.IterateDirectory(*MyConfigDirectoryTree,Visitor))
	{
		UE_LOG(LogTemp, Warning, TEXT("FilePaths: Directory's or files found"));
	}
	else
	{
		UE_LOG(LogTemp, Warning, TEXT("FilePaths: Directory did not exist or visitor returned false"));
	}

In this case, A bunch of folders and files are found that I put in the MyConfigDir folder as a test.

LogTemp: Warning: FilePaths: Directory found: D:/Projects/UE4/UFS/Config/MyConfigDir/ExampleFolder
LogTemp: Warning: FilePaths: Directory found: D:/Projects/UE4/UFS/Config/MyConfigDir/SecondFolder
LogTemp: Warning: FilePaths: File Found: D:/Projects/UE4/UFS/Config/MyConfigDir/TestFile1.txt
LogTemp: Warning: FilePaths: File Found: D:/Projects/UE4/UFS/Config/MyConfigDir/TestFile2.txt
LogTemp: Warning: FilePaths: Directory's or files found


How do I find all file's and folders in a directory Recursively[edit]

Doing this is almost the same as the IterateDirectory function. We need to create a Struct that inherits from IPlatformFile::FDirectoryVisitor And Overid

  struct DirectoryVisitor : public IPlatformFile::FDirectoryVisitor
{
	//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)
		{
			UE_LOG(LogTemp, Warning, TEXT("FilePaths: Directory found: %s"),FilenameOrDirectory);
		}
		else
		{
			UE_LOG(LogTemp, Warning, TEXT("FilePaths: File Found: %s"),FilenameOrDirectory);
		}
		return true;
	}
};

Now we have created the DirectoryVisitor struct we can use it in our code.

   FString MyConfigDirectoryTree = FPaths::ProjectConfigDir();
	MyConfigDirectoryTree.Append(TEXT("MyConfigDir"));
	IPlatformFile& FileManager = FPlatformFileManager::Get().GetPlatformFile();
    //Now we need to create a DirectoryVisitor 
	DirectoryVisitor Visitor;
    // Here is the only difference We call IterateDirectoryRecursively instead of IterateDirectory
    // The IterateDirectoryRecursively takes two arguments The directory and the Visitor we created above.
	if(FileManager.IterateDirectoryRecursively(*MyConfigDirectoryTree,Visitor))
	{
		UE_LOG(LogTemp, Warning, TEXT("FilePaths: Directory's or files found"));
	}
	else
	{
		UE_LOG(LogTemp, Warning, TEXT("FilePaths: Directory did not exist or visitor returned false"));
	}

In this case, A bunch of folders and files were found that I put in the MyConfigDir as a test.

LogTemp: Warning: FilePaths: Directory found: D:/Projects/UE4/UFS/Config/MyConfigDir/ExampleFolder
LogTemp: Warning: FilePaths: Directory found: D:/Projects/UE4/UFS/Config/MyConfigDir/SecondFolder
LogTemp: Warning: FilePaths: Directory found: D:/Projects/UE4/UFS/Config/MyConfigDir/SecondFolder/ThirdFolder
LogTemp: Warning: FilePaths: File Found: D:/Projects/UE4/UFS/Config/MyConfigDir/SecondFolder/ThirdFolder/ThirdFolderFileExampleOne.txt
LogTemp: Warning: FilePaths: File Found: D:/Projects/UE4/UFS/Config/MyConfigDir/SecondFolder/ThirdFolder/ThirdFolderFileExampleTwo.txt
LogTemp: Warning: FilePaths: File Found: D:/Projects/UE4/UFS/Config/MyConfigDir/TestFile1.txt
LogTemp: Warning: FilePaths: File Found: D:/Projects/UE4/UFS/Config/MyConfigDir/TestFile2.txt
LogTemp: Warning: FilePaths: Directory's or files found

As you can see, it finds more folders and file's because it also checked the folders inside the given directory.

FPlatformFileManager Working with Files and Directories[edit]

It is nice being able to get directories and files. But we have to do something with them. Here are some useful base functions like Copy, Delete, Move, ext.

Check if a file exist.[edit]

Before trying to manipulate a file, you have to make sure the file exists. If it does not exist, you will get into some nasty errors. To check if a file exists, we use the simple function.

.FileExist(TCHAR*);
</code>

Here is an example.
<code><syntaxhighlight lang="C++">
	FString MyFilePath = FPaths::ProjectConfigDir();
	MyFilePath.Append(TEXT("MyConfigDir/FakeConfig.txt"));
	IPlatformFile& FileManager = FPlatformFileManager::Get().GetPlatformFile();
	
	if(FileManager.FileExists(*MyFilePath))
	{
		UE_LOG(LogTemp, Warning, TEXT("FilePaths: File found!"));
	}
	else
	{
		UE_LOG(LogTemp, Warning, TEXT("FilePaths: File not found!"));
	}

The file exists and I got this in my LOG

LogTemp: Warning: FilePaths: File found!

LogTemp: Warning: FilePaths: File found!


Copy A file.[edit]

When you Copy a file, you keep the original. If you don't want that, then take a look at the move function.

We can copy the file using the function:

.CopyFile(TCHAR * Destination,TCHAR * source, EPlatformFileRead ReadFlags, EPlatformFileWrite WriteFlags)

Here is an example.

FString MyFileSource = FPaths::ProjectConfigDir();
MyFileSource.Append(TEXT("MyConfigDir/FakeConfig.txt"));

FString MyFileDestination = FPaths::ProjectConfigDir();
MyFileDestination.Append(TEXT("MyConfigDir/SecondFolder/FakeConfig.txt"));

IPlatformFile& FileManager = FPlatformFileManager::Get().GetPlatformFile();

UE_LOG(LogTemp, Warning, TEXT("FilePaths: Dest: %s"), *MyFileDestination);
UE_LOG(LogTemp, Warning, TEXT("FilePaths: Source: %s"), *MyFileSource);

if(FileManager.CopyFile(*MyFileDestination,*MyFileSource,EPlatformFileRead::None,EPlatformFileWrite::None))
{
   UE_LOG(LogTemp, Warning, TEXT("FilePaths: File Copied!"));
}
else
{
   UE_LOG(LogTemp, Warning, TEXT("FilePaths: File not Copied!"));
}

The file exists and I got this in my LOG

LogTemp: Warning: FilePaths: File Copied!


MoveFile[edit]

Move File is very simulair to copy File but it removes the original. It is also a bit simpler.

You can move files using the function:

.MoveFile(TCHAR* Destination,TCHAR* SOURCE);

Here is an example.

FString MyFileSource = FPaths::ProjectConfigDir();
MyFileSource.Append(TEXT("MyConfigDir/FakeConfig.txt"));

FString MyFileDestination = FPaths::ProjectConfigDir();
MyFileDestination.Append(TEXT("MyConfigDir/SecondFolder/FakeConfig.txt"));

IPlatformFile& FileManager = FPlatformFileManager::Get().GetPlatformFile();

if(FileManager.MoveFile(*MyFileDestination,*MyFileSource))
{
   UE_LOG(LogTemp, Warning, TEXT("FilePaths: File Moved!"));
}
else
{
   UE_LOG(LogTemp, Warning, TEXT("FilePaths: File not Moved!"));
}

The file exists and I got this in my LOG

LogTemp: Warning: FilePaths: File Moved!


Delete a file[edit]

If you want to delete a file it is quite simple.

.DeleteFile(TCHAR*))

Here is an example.

 FString FileToDelete = FPaths::ProjectConfigDir();
FileToDelete.Append(TEXT("MyConfigDir/FakeConfig.txt"));

IPlatformFile& FileManager = FPlatformFileManager::Get().GetPlatformFile();

if(FileManager.DeleteFile(*FileToDelete))
{
   UE_LOG(LogTemp, Warning, TEXT("FilePaths: File Deleted!"));
}
else
{
   UE_LOG(LogTemp, Warning, TEXT("FilePaths: File not Deleted!"));
}

The file exists and I got this in my LOG

LogTemp: Warning: FilePaths: File Deleted!


File Size[edit]

Getting the file size is a little bit more different from the other functions. It returns an Int with the size of the file in bytes instead of a bool.

To get the size of the file we use this function:

.FileSize(TCHAR*);

Here is an example.

FString File = FPaths::ProjectConfigDir();
File.Append(TEXT("MyConfigDir/FakeConfig.txt"));

IPlatformFile& FileManager = FPlatformFileManager::Get().GetPlatformFile();
// Getting the file size and storring it
int FileSize = FileManager.FileSize(*File);
//The file size is -1 if it is not found
if(FileSize > 0)
{
   UE_LOG(LogTemp, Warning, TEXT("FilePaths: File Size: %d"),FileSize);
}
else
{
   UE_LOG(LogTemp, Warning, TEXT("FilePaths: File not found!"));
}

The file exists and I got this in my LOG

LogTemp: Warning: FilePaths: File Size: 21


Documentation[edit]

Great with this, you should be able to control your folders and files. If you are having any trouble, consider taking a look at the official documentation.


Conclusion[edit]