Thread: binary read/write of objects

  1. #1
    ... arjunajay's Avatar
    Join Date
    May 2005
    Posts
    203

    Question binary read/write of objects

    I am intending to do a Phone-book program. I am thinking of creating some 'Person' Class. I want to write the names to the hard-disk. I am thinking of using binary read/write.
    I know that you have to use some 'read( )' / 'write( )' function.
    But I don't have a clue on binary read/write.
    Could some-one help me with binary read/writing of objects ?
    It will be sufficient if you just refer some tutorial site.

  2. #2
    Registered User
    Join Date
    Jun 2004
    Posts
    722
    In text mode you have fancy things like << operator, format strings (like those acepted by printf and so on), file read line by line, char* and std::string.

    In binary mode, the content of the file is ignored. Simply read n bytes to a buffer with allocated memory, or write those n byte from the buffer to the file. I don't know binary io in iso c++, but in ansi c is simply something like
    fread(buffer, size,1,file) and fwrite(buffer, size,1,file)
    since you don't know what the flie can store (that is, only by looking at it's content), you need to control well where each piece of binary information will be placed (at which byte offset).
    Last edited by xErath; 06-02-2005 at 10:16 PM.

  3. #3
    ... arjunajay's Avatar
    Join Date
    May 2005
    Posts
    203

    Exclamation c++

    Sorry for not informing
    This code is in c++.
    since you don't know what the flie can store (that is, only by looking at it's content), you need to control well where each piece of binary information will be placed (at which byte offset).
    and as for the byte offset it is obviously the size of the oject ('Person' here) is'nt it???

  4. #4
    Registered User
    Join Date
    Jun 2004
    Posts
    722
    yes, maybe. If you store two obecjt of type Person in a file, the first will be a offset 0, the second at offset sizeof(Person), and so on. Note that if Person contains pointer to memory or classes that internally keep pointers, when loading the object from the file those pointer wont be valid for sure, and you'll get segmentation faults

  5. #5
    ... arjunajay's Avatar
    Join Date
    May 2005
    Posts
    203

    Talking point

    Thanks I'll keep that in mind.
    I'm only new and my 'person' is very primitive and contain ony two (char*)s.

  6. #6
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    Binary reading/writing in C++ is done with the appropriate stream's read/write member function:

    Code:
    #include <fstream>
    
    ...
    
    // Reading
    std::ifstream in("input.txt",std::ios::binary|std::ios::in);
    
    ...
    
    in.read(...);
    
    
    // Writing
    std::ofstream out("output.txt",std::ios::binary|std::ios::out);
    
    ...
    
    out.write(...);
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  7. #7
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >I am thinking of creating some 'Person' Class.
    Cool.

    >I want to write the names to the hard-disk.
    More power to ya.

    >I am thinking of using binary read/write.
    Erm, probably not a good idea. Unless your Person class matches the very strict rules of a POD type, you'll be invoking undefined behavior. A safer method would be to work out some way to serialize the object so that it can be safely written to file (with the corresponding unserialize function to read it back and create an object safely). It could be as simple as making a string with the members formatted nicely:
    Code:
    // Serialize the first and last name
    std::string Person::toString() const
    {
      return std::string(first + '|' + last)'
    }
    Then you can simply write the resulting string to file:
    Code:
    file << myperson.toString();
    But don't use read() and write() unless you know the pitfalls, which you don't seem to.
    My best code is written with the delete key.

  8. #8
    Registered User
    Join Date
    Aug 2003
    Posts
    1,218
    Just a question...what exactly are the pitfalls? I have used read and write quite often and I havent found any problems with that so far.
    STL Util a small headers-only library with various utility functions. Mainly for fun but feedback is welcome.

  9. #9
    Registered User
    Join Date
    Mar 2002
    Posts
    1,595
    You have to learn sometime. If you want to learn how to do this given fair warning, thenhere's a reference. Start at C++ I/O and work your way through the options until you get to read() and write().

    http://www.cppreference.com/

    Some people will recommend you use C++ stlye casting rather than the C style casting that is demonstrated in the example provided at the above site, but that's a relatively minor problem.

    Is there a particular reason why you want to read and write all bytes of a "person" at once rather than with serial reads of each member data? All data written to and read from file is eventually involve binary data. Since most non-computers have more difficulty reading binary/hex than text, many programs do the conversions for you. To my knowledge you don't gain any "efficiency" by writing to file in binary and as already indicated if any data member are or contain memory addresses rather than primary data, then you will not be able to utilize direct binary read without some conversion anyway.
    You're only born perfect.

  10. #10
    ... arjunajay's Avatar
    Join Date
    May 2005
    Posts
    203
    First of all iused binary read / write beacause sinece every persons names are different, there would be no way of knowing where a person ends (everybody's names are different.)
    But in binary read / write, every object has the same length (every bit is written).
    so it is easier(or so I thought.)
    now I'm stuck on some file size problem in the same program.
    I'mposting it too...
    Are'nt I Annoying?

  11. #11
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    Quote Originally Posted by Shakti
    Just a question...what exactly are the pitfalls? I have used read and write quite often and I havent found any problems with that so far.

    Tell me this, if your person object contains two char* members representing the first and last names of the person (as mentioned by the poster), then if you simply write out the data for both these members to a file how do you know how much data to read back in later? If my name is "Bill Clinton" and I simply write out "BillClinton" to a file, when it comes time for me to read this back in, how many of those characters do I allocate to the first name and how many do I consider to belong to the last name? Do I read "BillC" into the first name and "linton" into the last? This problem comes up with any data that may be of variable length. Char pointers, strings, vectors of objects, etc... Unless your object is of fixed length, properly reading and writing the data to the file becomes more complicated.
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  12. #12
    ... arjunajay's Avatar
    Join Date
    May 2005
    Posts
    203
    That's why I was forced for a binary read/write.

  13. #13
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    First of all i used binary read / write beacause sinece every persons names are different, there would be no way of knowing where a person ends (everybody's names are different.)
    Really. Why can't a person's name end with a space or a newline?

    if you simply write out the data for both these members to a file how do you know how much data to read back in later?
    That's why I was forced for a binary read/write.
    I think you have that backwards. If you read and write in binary mode, you have no way of knowing how many bytes to read for a person's name. If you think you do, post how many bytes you are going to read for a name, and it will be trivial to show you a name that won't work.

    The fact that you don't know the exact number of bytes to read in seems to me to scream out DON'T USE BINARY MODE. Instead, your situation calls for using text mode and the insertion and extraction operators( << and >>) for formatted stream input and output.

    In my experience, you would do well to follow any advice Prelude gives you.
    Last edited by 7stud; 06-03-2005 at 02:20 PM.

  14. #14
    Anti-Poster
    Join Date
    Feb 2002
    Posts
    1,401
    Quote Originally Posted by elad
    You have to learn sometime. If you want to learn how to do this given fair warning, then here's a reference. Start at C++ I/O and work your way through the options until you get to read() and write().

    http://www.cppreference.com/
    Okay...that site wasn't exactly helpful. Good reference, but it didn't say anything about "pitfalls".
    Quote Originally Posted by hk_mp5kpdw
    Tell me this, if your person object contains two char* members representing the first and last names of the person (as mentioned by the poster), then if you simply write out the data for both these members to a file how do you know how much data to read back in later?
    Write it out as pascal strings instead of C-strings.

    I was unaware of any hidden pitfalls of using read() and write(). As long as you are careful to serialize everything so that it makes sense when you read it back in, it works fine. Am I missing something?
    If I did your homework for you, then you might pass your class without learning how to write a program like this. Then you might graduate and get your degree without learning how to write a program like this. You might become a professional programmer without knowing how to write a program like this. Someday you might work on a project with me without knowing how to write a program like this. Then I would have to do you serious bodily harm. - Jack Klein

  15. #15
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    >If you read and write in binary mode, you have no way of knowing how many bytes to read for a person's name.
    Well, you could just use a plain ole char array, and if it's part of a struct, read and write sizeof(struct).

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Binary Search Trees Part III
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 10-02-2004, 03:00 PM
  2. Request for comments
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 15
    Last Post: 01-02-2004, 10:33 AM
  3. File Encryption & Read/Write in Binary Mode
    By kuphryn in forum C++ Programming
    Replies: 5
    Last Post: 11-30-2001, 06:45 PM
  4. storing string objects to binary files
    By Unregistered in forum C++ Programming
    Replies: 2
    Last Post: 10-06-2001, 11:33 PM