I am using Rad Studio 10.2 Tokyo and I am wrapping IOS Native API. I am trying to get a filesize of a file called /Documents/test.txt which I can write and read using POSIX successfully but I am not able to get the filesize in anyway.
I get my path in different ways:
I have tried different ways by using POSIX API:
char path [256];
memset (path, 0, sizeof(path));
strcpy(path, getenv("HOME"));
strcat(path, "/Documents/test.txt");
long long fileSizeVal;
// Using lseek
int filesize= 0;
int fd = -1;
char path [256];
memset (path, 0, sizeof(path));
//HOME is the home directory of your application points to the root of your sandbox
strcpy(path, getenv("HOME"));
//concatenating the path string returned from HOME
strcat(path, "/Documents/test.txt");
fd = open (path, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP);
if (fd == -1) {
return -1;
}
filesize = lseek(fd, 0, 2);
Result: Filesize = 0
I tried by wrapping Objective-C code:
From native code:
NSDictionary* attributeDict = [[NSFileManager defaultManager] attributesOfItemAtPath:resourcePath error:nil];
NSNumber* fileSizeObj = [attributeDict objectForKey:NSFileSize];
long long fileSizeVal = [fileSizeObj longLongValue];
Wrapped into RadStudio:
_di_NSFileManager FileManager = TNSFileManager::Wrap(TNSFileManager::OCClass->defaultManager());
_di_NSDictionary attributeDict = FileManager->attributesOfFileSystemForPath(NSSTR(path), NULL);
_di_NSNumber fileSizeObj = TNSNumber::Wrap(TNSNumber::OCClass->numberWithLongLong(attributeDict->fileSize()));
fileSizeVal = fileSizeObj->longLongValue();
return fileSizeVal;
Result: fileSizeVal = 0
I tried using stat structure
struct stat stat1;
if( stat(path, &stat1) ) {
// something is wrong
}
long long size;
size = stat1.st_size;
return size;
Result: size= 0
The only thing I noted which I could not find any reference of Apple Developer site is that the AAAAAAAA-BB-CC-DD-ZZZZZZZZ is everytime different but I find the same "changing path" also with I read and Write the file successfully.
/private/var/mobile/Containers/Data/Application/AAAAAAAA-BBBB-CCCC-DDDD-ZZZZZZZZ/Documents/test.txt
while I should expect something like:
/Users/steve/Documents/MyFile.txt
I might be wrong in this assumption tough.
I am very frustrated.
Any suggestion??
I checked if the File exist after writing it:
bool Exists = false;
_di_NSFileManager FileManager = TNSFileManager::Wrap(TNSFileManager::OCClass->defaultManager());
if (FileManager)
{
Exists = FileManager->fileExistsAtPath(NSSTR(path));
if (Exists == true)
return 1;
else
return 0;
}
And it correctly return the answer so the file is written correctly and when I read it back in POSIX it returns me the correct bytes.
Finally after compiling the code on XCode I've noticed different behaviors from RadStudio compiled code and X-Code.
But nevermind I am pleased to post my solution to Read, Write a file using POSIX in RadStudio on iOS:
int iOS_WriteFile (char * FileName, char * BufferToWrite, int Lenght, int mode)
{
int fd = -1;
int iResult = -1;
char path [PATHSIZE];
bool FileExists = false;
//mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
memset (path, 0, sizeof(path));
iOS_GetApplicationPath (path);
strcat (path, FileName);
// Check if a NEWFILE is needed or append to existing one
if (mode == NEWFILE)
{
// Creates it (if it does not already exist), or truncates its length to 0 (if it does exist).
fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
// This creates a file if it does not exist
//fd = open(path, O_WRONLY | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
}
if (mode == APPEND)
{
FileExists = iOS_FileExists (FileName);
if (FileExists == false) {
return IOS_ERROR_FILE_DOES_NOT_EXIST; // File Does not exist return appropriate ERROR
}
// File Exists so write it in append mode
fd = open(path, O_WRONLY | O_APPEND);
}
if (fd < 0) {
return IOS_ERROR_FILE_OPEN_ERROR;
}
//Writing Buffer
iResult = write (fd, BufferToWrite, Lenght);
if (iResult != Lenght) {
// Something went Wrong in writing the file
//Closing the file
close(fd);
return IOS_ERROR_FILE_WRITE_LENGH_ERROR;
}
//Closing the file
close(fd);
return iResult;
}
Here comes my two routines to get the Path of the Application:
void iOS_GetApplicationPath (char * ApplicationPath)
{
char path [PATHSIZE];
memset (path, 0, sizeof(path));
//---- Get Path with "getenv" -------
//HOME is the home directory of your application points to the root of your sandbox
strcpy(path, getenv("HOME"));
strcpy (ApplicationPath, path);
}
of this one using wrapped iOS API:
void iOS_Native_GetApplicationPath (char * ApplicationPath)
{
char path [PATHSIZE];
// Get Home Directory using NSHomeDirectory () function
void * GetHomeDir = NSHomeDirectory ();
char * cHomeDir;
// Get Home Directory
_di_NSString HomeDir = TNSString::Wrap(NSHomeDirectory());
UnicodeString HD;
// Convert Home Directori NSString to UnicodeStrting
HD = NSStrToStr (HomeDir);
// Stitch filename to Home Directory
memset (path, 0, sizeof(path));
Mobile_ConvertUnicodeStringToChar (HD, path); // Convert UnicodeString to char
strcpy (ApplicationPath, path);
}
here is my Read Routine:
int iOS_ReadFile (char * FileName, char * BufferToReturn, int Length)
{
int fd = -1;
int iResult = -1;
char path [PATHSIZE];
bool FileExists = false;
char * ReadBuffer;
memset (path, 0, sizeof(path));
iOS_GetApplicationPath (path);
strcat (path, FileName);
// Open in Read Only
fd = open(path, O_RDONLY);
if (fd > 0) {
// Read File
ReadBuffer = (char*) malloc(sizeof(char) * (Length + 1));
iResult = read(fd, ReadBuffer, Length);
if (iResult != Length) {
close (fd);
return IOS_ERROR_FILE_READ_LENGH_ERROR;
}
else
{
memcpy (BufferToReturn, ReadBuffer, Length);
close (fd);
return iResult;
}
}
// File does not open
if (fd < 0) {
return IOS_ERROR_FILE_OPEN_ERROR;
}
}
and finally where it all started it all ends with the File Size Routine:
long long iOS_GetFileSize (char * filename)
{
char path [PATHSIZE];
memset (path, 0, sizeof(path));
iOS_GetApplicationPath (path);
strcat (path, filename);
int fd = -1;
long long FileSize;
// Open in Read Only
fd = open(path, O_RDONLY);
if (fd > 0) {
// Get untill the end of the file
FileSize = lseek(fd, 0, SEEK_END);
close (fd);
}
if (fd < 0) {
return IOS_ERROR_FILE_OPEN_ERROR;
}
else
return FileSize;
}
I do not know why people here do not help much each other. This is the result of a week of hard job trying to make simple functions work on iOS using Posix API in Rad Studio by Embarcadero. I hope somebody will appreciate my contribute to the community and save people's precious time...
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.