View Full Version : Carbon - Reading / Writing Text Files
dave05
2006.07.12, 03:38 AM
is there a better way than fopen/fread/fwrite to open, read from, and write to a text file that is located in the project bundle? I don't know how CGDataproviders work, and I don't understand how to retrieve the bundle path for fopen().
Any suggestions?
Thanks so much in advance.
OneSadCookie
2006.07.12, 06:39 AM
CFBundle will get you paths to your resources.
I'd stick with fopen & friends personally, though there are *many* other options.
sealfin
2006.07.12, 06:48 AM
[...]I don't understand how to retrieve the bundle path for fopen()[...]
I'm not absolutely sure what you meant by the above, but the code below will switch the CWD to the Resources directory within your application's bundle...
CFURLRef resourcesURL;
char resourcesPath[ 4096 ];
resourcesURL = CFBundleCopyResourcesDirectoryURL( CFBundleGetMainBundle());
CFURLGetFileSystemRepresentation( resourcesURL, 1, resourcesPath, 4096 );
chdir( resourcesPath );
dave05
2006.07.12, 07:23 PM
as always, this forum delivers. I posted the thread late last night and later realized that CGDataproviders are for "core graphics".
dave05
2006.07.31, 11:22 PM
hey everyone.
I used the suggestions made above in the thread to implement file "loading". That is, there are a set # of player slots and 1 text file in my project bundle. The text file is read when the application is launched:
FILE *pfile = fopen("PlayerFile.txt", "r");
etc, etc, etc
fclose(pfile);
this part works without a problem. writing to the file proves otherwise:
FILE *pfile = fopen("PlayerFile.txt", "w");
etc, etc, etc
fclose(pfile);
the above code did not work, and in fact resulted in an error when attempting to load the file on my next debug-test-run. I also tried opening and writing to a completely new text file, but after writing to the file (called newfile.txt) and quitting my application, no file was created! Not only was there no file called newfile.txt in my project directory in the Resources folder (where i'd like to load and save my file), but a harddisk search also found no such file.
additional question(s):
when writing a string to a file, is the size_t of the string just the length of the string, or the length * sizeof(char)? does this differ between using "wb" and "w" / "rb" and "r"? For text files, i'm pretty sure i should be sticking with non-binary reads and writes. i know someone can shed some light. thanks in advance as always
aarku
2006.07.31, 11:29 PM
I'm not absolutely sure what you meant by the above, but the code below will switch the CWD to the Resources directory within your application's bundle...
CFURLRef resourcesURL;
char resourcesPath[ 4096 ];
resourcesURL = CFBundleCopyResourcesDirectoryURL( CFBundleGetMainBundle());
CFURLGetFileSystemRepresentation( resourcesURL, 1, resourcesPath, 4096 );
chdir( resourcesPath );
Shouldn't you be using PATH_MAX instead of 4096?
OneSadCookie
2006.07.31, 11:34 PM
PATH_MAX is actually less than 4096, I think, so it's probably not an issue. It is the correct thing to do, though.
I'm sure this is not your problem, but you should *never* write to a file inside your application bundle. The user may not have permission to do so. This is what ~/Library is for :)
"w" says to stdio, "please feel free to screw around with what I write in any way you feel like", where "wb" says "please preserve exactly what I write". On Mac OS X (and all unixes) there's no difference between the two. On Windows, "w" will translate "\n" to "\r\n", and "r" will translate "\r\n" to "\n".
If your file is not being created, you need to check that fopen() is returning a non-NULL pointer, and that you are actually calling fclose.
dave05
2006.08.01, 12:01 AM
so just to be clear, if i were to call chdir("~/Library/somefoldername") and the folder did not exist, how would i determine it did not exist? does mkdir work in C? (i read the man file and it seems highly unlikely)
[ps i think that is my problem...]
... also, i want the save file to be kind of hard to hack... so that's why i wrote the file to the bundle in the first place, but i guess that's not a good way to do it? .. guess i could encode it. :(
ThemsAllTook
2006.08.01, 12:09 AM
does mkdir work in C? (i read the man file and it seems highly unlikely)
man 2 mkdir is probably closer to what you want.
OneSadCookie
2006.08.01, 12:09 AM
I think you have worse problems than people hacking your data file :p
mkdir() is a C function -- read "man 2 mkdir"
Note that ~ is a shell expression; you need to find the user's home directory yourself. The unix function getpwuid can do that, or there may be an easier Carbon equivalent.
Also note that you should put your file in ~/Library/Application Support/YourAppName/
dave05
2006.08.01, 09:42 PM
worse problems indeed...
anyways i searched the net and found my solution/
posted by OSC himself! haha
http://www.idevapps.com/forum/archive/index.php/t-2817.html
#define _RWXAccessAll (S_IRWXU | S_IRWXG | S_IRWXO)
void FH_SetLibraryDirectory()
{
char *libraryPath;
libraryPath = malloc(128 * sizeof(char));
libraryPath = strcat(getenv("HOME"), "/Library/Application Support");
chdir( libraryPath );
if (mkdir("My App", _RWXAccessAll) == 0)
printf("Created a new directory in /Library/Application Support");
chdir("My App");
}
vBulletin® v3.6.8, Copyright ©2000-2008, Jelsoft Enterprises Ltd.