Mailing Lists: Apple Mailing Lists

Image of Mac OS face in stamp
 
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Best way to do simple binary file I/O?



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:
http://lists.apple.com/mailman/options/cocoa-dev/email@hidden

This email sent to email@hidden
References: 
 >Re: Best way to do simple binary file I/O? (From: James Merkel <email@hidden>)



Visit the Apple Store online or at retail locations.
1-800-MY-APPLE

Contact Apple | Terms of Use | Privacy Policy

Copyright © 2007 Apple Inc. All rights reserved.