Saving user preferences and files

_sergey_

No Reptile Testing
What is the best way to save user preferences and files (binary data which is too large to be stored in .plist's)?

I use the following code to save a file:
Code:
char full_filename[50];
FILE *F;

// fopen doesn't understand the ~ symbol in path, so the path needs to be formed manually
sprintf(full_filename, "%s/Library/MyProgramName/filename.ext", getpwnam(getlogin())->pw_dir);

F = fopen(full_filename, "w");

// if fopen fails, probably there's no such folder
if (!F)
{
    // create the folder
    system("mkdir ~/Library/MyProgramName");
    // and try again
    F = fopen(full_filename, "w");
}

if (F)
{
    // load the data with fread calls
}

fclose(F);

Though with doesn't work on some Macs (not depending on the Mac OS X version).
Is there a more elegant and correct way to do this? I belive there is.

Please suggest.
 
For one thing, you can't open the file with only write "w" access and then expect to use fread on it. Try "r+" mode. Other than that, I can't see how the code doesn't work.
 
With the aforementioned mode problem, that code should work on any OS X system. You'd have to be more specific about where it's failing.

For user preferences, the *right* way to save them on OS X is using the CFPreferences API. Do a search on developer.apple.com.

If the data is too large or needs to be in binary format, then you're back to fopen/fwrite/fread.

Wade
 
wadesworld said:
With the aforementioned mode problem, that code should work on any OS X system. You'd have to be more specific about where it's failing.
If only I knew where.

I'm starting to believe that the problem isn't in this code, but in something else, and we unintentionally fixed that recently :) because it all seems to work at all computers now. If you say the code is OK, it really must be so.
Anyway, when something suddenly gets fixed itself, it's very suspicious...
 
_sergey_ said:
If only I knew where.

I'm starting to believe that the problem isn't in this code, but in something else, and we unintentionally fixed that recently :) because it all seems to work at all computers now. If you say the code is OK, it really must be so.
Anyway, when something suddenly gets fixed itself, it's very suspicious...

Well, you do understand that it will fail if full_filename is more than 50 characters, right? You probably should make full_filename the length of a maximum allowable pathname, which I believe is defined as MAX_PATH and is 1024 bytes.

Wade
 
wadesworld said:
Well, you do understand that it will fail if full_filename is more than 50 characters, right? You probably should make full_filename the length of a maximum allowable pathname, which I believe is defined as MAX_PATH and is 1024 bytes.
We extended it to 200 charcaters. Maybe that was what helped.

Yes, really
/Users/.../Library/ProgramName/...
is more than 30 characters already
 
_sergey_ said:
We extended it to 200 charcaters. Maybe that was what helped.

Yes, really
/Users/.../Library/ProgramName/...
is more than 30 characters already

Extend it to 1024 - really. It's 1,000 bytes. That's absolutely nothing and certainly worth it to ensure no path will overflow your buffer. I commend your desire to save memory but in this case, making sure the buffer is of sufficient size to handle the maximum allowable pathname is not memory wasted.

Wade
 
Or better yet, use dynamic allocation a la NSString. Then load your data using NSData. Unless using Cocoa is a problem, which is only if you're targeting Carbon or strictly UNIX.
 
Back
Top