I’m working on a custom, artist-editable UI solution to replace Slate on our project, and as part of that, I need to write to text files (since we edit our UI layouts at runtime, and AFAIK there’s no way to make permanent changes to the level objects in the editor from the game).
Right now we’re using FPlatformFileManager for this, like so:
This ends up writing the file to UnrealEngine/Engine/Binaries, which probably isn’t where we want it – we’d rather it be in Config or somewhere like that.
Related questions:
Should we be using FPlatformFileManager for this?
If not, what’s the best way to do it?
If so, how best to specify the file folder for placement?
Alternatively, is there a way to modify .ini files at runtime?
I thus make your entire project super happy fun with this one .h file !!!
Read all the functions here!!!
CoreMisc.h
/**
* Parses a string into tokens, separating switches (beginning with - or /) from
* other parameters
*
* @param CmdLine the string to parse
* @param Tokens [out] filled with all parameters found in the string
* @param Switches [out] filled with all switches found in the string
*/
static void Parse(const TCHAR* CmdLine, TArray<FString>& Tokens, TArray<FString>& Switches);
/**
* Load a text file to an FString.
* Supports all combination of ANSI/Unicode files and platforms.
* @param Result string representation of the loaded file
* @param Filename name of the file to load
* @param VerifyFlags flags controlling the hash verification behavior ( see EHashOptions )
*/
static bool LoadFileToString( FString& Result, const TCHAR* Filename, uint32 VerifyFlags=0 );
/**
* Write the FString to a file.
* Supports all combination of ANSI/Unicode files and platforms.
*/
static bool SaveStringToFile( const FString& String, const TCHAR* Filename, EEncodingOptions::Type EncodingOptions=EEncodingOptions::AutoDetect, IFileManager* FileManager=&IFileManager::Get() );
/**
* Load the given ANSI text file to an array of strings - one FString per line of the file.
* Intended for use in simple text parsing actions
*
* @param InFilename The text file to read, full path
* @param InFileManager The filemanager to use - NULL will use &IFileManager::Get()
* @param OutStrings The array of FStrings to fill in
*
* @return bool true if successful, false if not
*/
static bool LoadANSITextFileToStrings(const TCHAR* InFilename, IFileManager* InFileManager, TArray<FString>& OutStrings);
#Save Text Files Anywhere You Want
You can save a text file anywhere you want !
You can also load and PARSE a string!!!
This parsing should make your entire goal great fun
#FileHelper
You need to preface the above functions with FFileHelper::
#New Method of File Management
My code below is old
see my tutorial here for the new File Management functions
GFileManager no longer exists
Wiki link
#My Function For You
bool UVictoryBPFunctionLibrary::SaveStringTextToFile(
FString SaveDirectory,
FString FileName,
FString SaveText,
bool AllowOverWriting
){
//GFileManager?
if (!GFileManager) return false;
//Dir Exists?
if ( !GFileManager->DirectoryExists( *SaveDirectory))
{
//create directory if it not exist
GFileManager->MakeDirectory( *SaveDirectory);
//still could not make directory?
if (!GFileManager->DirectoryExists( *SaveDirectory))
{
//Could not make the specified directory
return false;
//~~~~~~~~~~~~~~~~~~~~~~
}
}
//get complete file path
SaveDirectory += "\\";
SaveDirectory += FileName;
//No over-writing?
if (!AllowOverWriting)
{
//Check if file exists already
if (GFileManager->GetFileAgeSeconds( * SaveDirectory) > 0)
{
//no overwriting
return false;
}
}
return FFileHelper::SaveStringToFile(SaveText, * SaveDirectory);
}
#LoadStringFromTextFile
/**
* Load a text file to an FString.
* Supports all combination of ANSI/Unicode files and platforms.
* @param Result string representation of the loaded file
* @param Filename name of the file to load
* @param VerifyFlags flags controlling the hash verification behavior ( see EHashOptions )
*/
static bool LoadFileToString( FString& Result, const TCHAR* Filename, uint32 VerifyFlags=0 );
Blargh … It still writes it to Engine/Binaries (actually, Engine/Binaries/Win64 this time).
Any idea how to fix this? I could try using “…\OurGameName\Config” but it’s in a different folder for everyone on our team … and the end user isn’t (presumably) going to have an Engine/Binaries folder.
All of the functions you could ever want for this are in Paths.h
Used with FPaths::
#Example1
/**
* Returns the base directory of the current game by looking at the global
* GGameName variable. This is usually a subdirectory of the installation
* root directory and can be overridden on the command line to allow self
* contained mod support.
*
* @return base directory
*/
static FString GameDir();