Young_Wolf
(Young_Wolf)
January 24, 2017, 8:34pm
1
Hello unreal engineers,
I’m trying to write FString data to binary file in UE4, and I’ve been following Rama’s tutorial on writing data to files.
Thanks to his help I managed to write those two functions:
Save String Function
FString SaveDirectory = FString("E:/UESaves");
FString FileName = FString("UE4Save.bin");
FString TextToSave = FString("YoungWolf?db235ccsa432ds");
bool bAllowOverwriting = false;
IPlatformFile& PlatformFile = FPlatformFileManager::Get().GetPlatformFile();
FString FullPath = SaveDirectory + "/" + FileName;
IFileHandle* FileHandle = PlatformFile.OpenWrite(*FullPath);
if (FileHandle)
{
FileHandle->Write((const uint8*)TCHAR_TO_ANSI(*TextToSave), TextToSave.Len());
delete FileHandle;
}
Load String Function
FString SaveDirectory = FString("E:/UESaves");
FString FileName = FString("UE4Save.bin");
FString TextToSave = FString("YoungWolf?db235ccsa432ds");
bool bAllowOverwriting = false;
IPlatformFile& PlatformFile = FPlatformFileManager::Get().GetPlatformFile();
FString FullPath = SaveDirectory + "/" + FileName;
IFileHandle* FileHandle = PlatformFile.OpenRead(*FullPath);
if (FileHandle)
{
int64 size = GetFileSizeOf(FullPath);
//Allocate uint8 buffer with size
uint8* ByteArray = reinterpret_cast<uint8*>(FMemory::Malloc(size + 1));
//Read Data to buffer
FileHandle->Read(ByteArray, size);
//Convert to decimal here..
delete FileHandle;
}
What I’ve tried is:
FString ActualString = FString::FromBlob(ByteArray, size);
FString ActualString = FString::FromHexBlob(ByteArray, size);
and been googleing around for hours, but sadly, no information on the topic. Can anyone help me?
UnrealString.h has BytesToString() and StringToBytes() functions.
1 Like
Young_Wolf
(Young_Wolf)
January 24, 2017, 9:38pm
3
I just checked them out, but the converted string is not the same.
Original: YoungWolf?db235ccsa432ds
Recovered: ZpvohXpmg@ec346ddtb543et
Now that I compare them it feels like the original string had all the letters +1. Probably to the fact that when converting to binary, the original text that was UTF16 was converted to ANSI. Maybe that’s why it’s different?
So y +1 = z
o +1 = p
Now I can do either convert the recovered string with -1 to each individual letters, tho I’m not sure how. Would tchar - 1 work?
Or there is a way to get the string correctly?
Young_Wolf
(Young_Wolf)
January 24, 2017, 11:44pm
5
Hmm thanks for the link. Reading through it, and learned that the funcs are broken when passing UTF16 binary arrays. Haven’t been fixed since 12.5 version of the engine. Now what? Guess I’m in a dead end.
Young_Wolf
(Young_Wolf)
January 24, 2017, 11:59pm
6
I was able to fix it. Here’s the function I wrote:
FString Fixed;
for (int i = 0; i < BrokenString.Len(); i++)
{
const TCHAR c = BrokenString* - 1;
Fixed.AppendChar(c);
}
return Fixed;
I hope it might work out for someone out there who stuggles! Just note that it will only work if the entire string is broken.
3 Likes
Worked for me, I just made a wrapper function to make it easier on me:
FString BytesToStringFixed(const uint8 *In, int32 Count)
{
FString Broken = BytesToString(In, Count);
FString Fixed;
for (int i = 0; i < Broken.Len(); i++)
{
const TCHAR c = Broken* - 1;
Fixed.AppendChar(c);
}
return Fixed;
}
Talad
(Talad)
June 22, 2021, 10:56am
8
Had the same issue with 4.26.2, the Unreal engine issue report says they will not fix it. (Unreal Engine Issues and Bug Tracker (UE-33889) )
I dont fully understand the implications of the null pointer terminator described in their comment:
// Put the byte into an int16 and add 1 to it, this keeps anything from being put into the string as a null terminator
But anyway I created my own function like this modifying theirs. So far seems to work ok.
inline FString UFileDownloader::MyBytesToString(const uint8* In, int32 Count)
{
FString Result;
Result.Empty(Count);
while (Count)
{
int16 Value = *In;
Result += TCHAR(Value);
++In;
Count--;
}
return Result;
}
4 Likes
DentonJC
(JC_Denton)
September 9, 2022, 9:26pm
9
This does the trick
TArray<uint8> content;
const std::string cstr(reinterpret_cast<const char*>(content.GetData()), content.Num());
FString frameAsFString = cstr.c_str();
UE_LOG(VRSLog, Warning, TEXT("%s"), *frameAsFString);
Narg666
(Narg666)
March 18, 2023, 8:50pm
11
Doesn’t work for me.
For some reason it is returning empty.
TArray<uint8> ReceiveData;
FString result = FString(UTF8_TO_TCHAR(ReceiveData.GetData())); ← not safe enough
this works for non-ansi wide char , “像是中文”
FString result = FString(ReceiveData.Num(), UTF8_TO_TCHAR(ReceiveData.GetData())); ← this one better
6 Likes