• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Best way to do simple binary file I/O?
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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


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

  • Prev by Date: Re: Building a dynamic class factory ( +load init order)
  • Next by Date: Insert text into NSTextView/NSTextStorage does not work
  • Previous by thread: Re: Best way to do simple binary file I/O?
  • Next by thread: Unit Testing
  • Index(es):
    • Date
    • Thread