Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

Dirk Gregorius

Binary file streams

This topic is 5321 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Is there standard way of using the stream operators <<,>> with binary files? Lets say we have two structs like this: struct Header { int Magic; int NumElements; } struct Element { int Data; char Data2[128]; } and a binary file which holds the header and then n Elements objects. We first read the header and then the elements. Would it make sense to define a istream operators >> like this: std::istream& operator>>(std::istream& is, Header& header) { return is.read( reinterpret_cast(&header), sizeof(Header) ); } And the same for the Element struct. The we could do something like this: std::vector g_Data; void ImportData(const std::string& filename) { // I don''t use any error checking here for clarity... std::ifstream is(filename, std::ios::in|std::ios::binary); Header header; is >> header; g_Data.resize(header.NumElements); Element e; for (int i = 0; i < header.NumElements; ++i) { is >> e; g_Data = e; } } What I wonder if the use of the reinterpret_cast is correct and good style? What do you think of this implementation? Is there a better/standard way of parsing files with the above structure using the stream classes? What about speed issues? As in my previous post "memcpy vs. std::copy" are there any differences between the C-Functions (fread,...) and the Standard Library counterparts, especially regarding speed issues? Any examples or references that you could recommend? Help / critic / comments are greatly appreciated :-) -Dirk

Share this post


Link to post
Share on other sites
Advertisement
I''d forget the << and >> operators. They''re intended for formatted input/output and imply whitespace-terminated data.

You also shouldn''t use reinterpret_cast. static_cast should be fine, I believe.

I doubt you''ll have any speed issues. Try it and see. Don''t worry about speed until you know you have a problem.

[ MSVC Fixes | STL Docs | SDL | Game AI | Sockets | C++ Faq Lite | Boost
Asking Questions | Organising code files | My stuff | Tiny XML | STLPort]

Share this post


Link to post
Share on other sites
>>I''d forget the << and >> operators. They''re intended for
>>formatted input/output and imply whitespace-terminated data.

Are sure about that? Aren''t these operators implement in the derived classes? If yes, would it make to implement them the way you describe it?

-Dirk

Share this post


Link to post
Share on other sites
I just looked through the internet - so can somebode say if this holds true:

The stream operators >> and << are for formated I/O only, so when parsing binary files (which are NOT formated)I have to use read() and write() instead - very similiar like with the C counterparts, correct?

-Dirk

Share this post


Link to post
Share on other sites
The >> and << operators for the standard streams are intended for formatted text I/O. If you mix in binary I/O, the parsers will get confused.

std::istream& operator>>(std::istream& is, Header& header)
{
extract binary data
}
...
ifstream file;
int x, y;
Header h;
...
file >> x >> h >> y; // this is not likely to work


If you want, you can write your own stream classes that use the << and >> operators for binary data (for example, a yet-another-zlib-compressed stream).

Share this post


Link to post
Share on other sites
quote:
The stream operators >> and << are for formated I/O offly, so when parsing binary files (which are NOT formated)I have to use read() and write() instead - very similiar like with the C counterparts, correct?

"binary", in this context, means merely "no platform-dependent transformations are performed". Common transforms are the conversion from \n to \r\n, and \n to \r. Other transformations that have occurred historically include appending an EOF character to the end of a file.

Binary does not mean "unformatted".

Share this post


Link to post
Share on other sites

template<class Data> class raw_proxy
{
public:
raw_proxy( Data& data ) : ptr( &data ), data_size( sizeof( Data ) ) {}
raw_proxy( Data& data, size_t size ) : ptr( &data ), data_size( size ) {}
Data* get_ptr() const { return ptr; }
std::streamsize get_size() const { return (std::streamsize)data_size; };
private:
Data* ptr;
size_t data_size;
};

template<class Data> raw_proxy<Data> raw( Data& data )
{
return raw_proxy<Data>( data );
}

template<class Data> raw_proxy<const Data> raw( const Data& data )
{
return raw_proxy<const Data>( data );
}

template<class Data> raw_proxy<Data> raw( Data& data, size_t size )
{
return raw_proxy<Data>( data, size );
}

template<class Data> raw_proxy<const Data> raw( const Data& data, size_t size )
{
return raw_proxy<const Data>( data, size );
}

template<class OS, class Data>
OS& operator<<( OS& os, const raw_proxy<Data>& proxy )
{
typedef const OS::char_type* pointer_type;
return os.write( reinterpret_cast<pointer_type>(proxy.get_ptr()), proxy.get_size() );
}

template<class IS, class Data>
IS& operator>>( IS& is, const raw_proxy<Data>& proxy )
{
typedef IS::char_type* pointer_type;
return is.read( reinterpret_cast<pointer_type>(proxy.get_ptr()), proxy.get_size() );
}


Usage:

input_stream >> raw( variable );
output_stream << raw( variable_or_constant );



“Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.”
— Brian W. Kernighan (C programming language co-inventor)

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!