Re: Best way to do simple binary file I/O?
Re: Best way to do simple binary file I/O?
- Subject: Re: Best way to do simple binary file I/O?
- From: Uli Kusterer <email@hidden>
- Date: Sat, 29 Dec 2007 11:24:35 +0100
On 29.12.2007, at 8:31 , James Merkel wrote:
Charles Steinman wrote:
Just as a reminder: Raw binary I/O like this is likely
to break across architectures. It also doesn't mesh
very well with Cocoa objects, whose internal structure
is generally private. The safer and more standard
Cocoa way of doing it would be either to write an
XML/plist document or to archive objects with
NSKeyedArchiver.
I don't see why you can't use the standard C file I/O functions
(fopen, fread etc) in Objective C. I have been doing this for a long
time on both Intel and PPC machines and have had no problems. By the
way doesn't fread have four parameters ?
If you take account of some differences, fread() or any other raw
read/write method is OK. If you're saving objects, they are
effectively structs for this discussion. Also, NSObject's ivars are
private, so you can't save those, and need to re-create the right
subclass after loading an object, too. NS(Keyed)Archiver and Co. take
care of that for you. So, if you're not doing something that needs to
be loaded partially and needs to be random access, an archiver is
usually less hassle.
If you're using fread() the way the OP mentioned, then either you're
saving only one-byte quantities (like ASCII or UTF8 text, or uint8_t
and char types) or you never tried to take one of your files from an
Intel Mac to a PPC Mac or the other way round:
The endian-ness (order in which the individual bytes of a multi-byte
type like an int are stored (sizeof(int)==4 on 32-bit MacOS X builds))
differs between those platforms, and if you save on one platform and
read on the other, your numbers get 'reversed' and you get nonsense
numbers.
The usual solution is to either save everything in one computer's
endian-ness and have all others convert, or to store a byte-order
marker at the start of the file (e.g. the number 1 as a short, which
is 0x0100 on Intel, and 0x0001 on PPC), and then to convert if the
number is not 1.
Of course, if you save a whole struct, padding bytes that get
inserted into structs to force better performance by aligning fields
on their native boundaries can screw you over, because those can
differ depending on CPU. I think on OS X most of the types are the
same, but IIRC there were a few that didn't (floats? I'd have to check
my file access library). I generally don't save whole structs, and
rather each field separately, as you'd do with NSArchiver.
Cheers,
-- M. Uli Kusterer
"The Witnesses of TeachText are everywhere..."
http://www.zathras.de
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden