Jump to content
  • Advertisement

Archived

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

Kylotan

Binary Streams

This topic is 6941 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

I don't usually have a problem with C++ streams, but it's been a while since I did much in detail with them, so I am unsure what the problem is here. Here's my stripped down code:
#include <sstream>
#include <fstream>
#include <iostream>
using namespace std;

int main()
{
	stringstream destination_buffer(ios::binary);
	ifstream input_file("c:/somefile.raw", ios::binary);

	destination_buffer << input_file.rdbuf();

	string word;
	while (destination_buffer >> word)
		cout << word;

	cout << "All done." << endl;

	return 1;
}
 
The idea being to open a file, read it all into a stringstream, and then use cout to write it. If I don't set both streams to binary, I won't be able to read the whole file (a graphic). But setting them to binary, it seems that there is never anything in the stringstream. I'm getting the impression stringstreams aren't much good at dealing with binary data, right? All I am trying to do is pretty much get that whole file buffered into memory. So, what am I doing wrong, and what should I be doing instead? Edited by - Kylotan on 4/21/00 8:36:55 PM

Share this post


Link to post
Share on other sites
Advertisement
Well, one possible problem may be the use of just the ios::binary flag. I believe you have to use ios::in / ios::binary to read in from a binary file using streams.


Edited by - rimtgd on 4/22/00 2:49:12 AM

Share this post


Link to post
Share on other sites
I''d think that the problem is that you''re using << to read from the file, and that doesn''t work if the file is opened in binary mode. istream::read(char_type *s, streamsize size) does work in binary mode, however.

Isn''t reading it in to a char array and passing that to a stringstream ctor an option? I''m not that experienced with stringstreams to give a more elegant solution...

Erik

Share this post


Link to post
Share on other sites
quote:
Original post by Erik Post

I'd think that the problem is that you're using << to read from the file, and that doesn't work if the file is opened in binary mode. istream::read(char_type *s, streamsize size) does work in binary mode, however.


I figured that might be the case. But I want to be able to read the whole stream in one function, and this is where the "<< stream.rdbuf()" syntax is useful. I can't seem to find any other function that will load a streambuf without stopping at a delimiter.

quote:
Isn't reading it in to a char array and passing that to a stringstream ctor an option?


Right now, since nothing works and I -need- this to work asap (it's my tile-loading routine), anything is an option :/ However the benefits I was trying to get by copying stream to stream is (a) not having to worry about the file size (I will need to find that out to allocate the memory I guess) and (b) performance (reading an entire stream in one call gives your disk the best opportunity to perform read-ahead caching etc).

Thanks for the help.

(10 minutes later) Ah... having given it some thought, I can't just pass a char* to a stringstream constructor, as I will have plenty of '0's in my binary file. This will result in it only reading in part of the string Any other ideas?

Edited by - Kylotan on 4/22/00 6:32:25 AM

Share this post


Link to post
Share on other sites
Ok, I still want the original question answered, as that is how I''d prefer to do it. I made a workaround, but this is just as unsatisfactory. Here''s the code:

// Load in the graphics file

// object to store the loaded data
stringstream fileBuffer;

ifstream file(filename2.c_str(), ios::binary/ios::in);

// Method 2.
// Find file size
int filesize;
file.seekg(0, ios::end); // move to end of file
filesize = file.tellg();
file.seekg(0, ios::beg); // back to start
{
stringstream msg;
msg << "Grabbed filesize: " << filesize;
theApp.LogMsg(msg.str());
}
// Allocate byte array as destination for data
char* buffer = new char[filesize];
// Fill it from file
theApp.LogMsg("About to read in buffer.");
file.read(buffer, filesize);
// Fill the stringstream with it
theApp.LogMsg("About to write out buffer.");
fileBuffer.write(buffer, filesize);


Now, checking my logging functions, everything runs ok until it hits the last line. Basically, it takes over 2 minutes for the write() function (one of the more efficient ones, I would have thought) to load a 360k bitmap into that stringstream! About 2 seconds to read it from disk and 140 to write it into memory. What''s the problem here?

Share this post


Link to post
Share on other sites
I''d just use the ofstream object here. I''ve had no problems with it. (In fact, I''m waiting for GameDev to post my article on file streams, but...). It works just the same as the ifstream, but I''m sure you already know or can figure it out. Then use that for writing, and you can write whatever bytes are in the stringstream. That could solve your problem.


ColdfireV

Share this post


Link to post
Share on other sites
ColdfireV, I''m assuming you mean to just pass the ifstream around rather than a stringstream, after all, I don''t need an ofstream after that point. I had just wanted to be able to load it into memory and close the file immediately for performance purposes, but obviously there is some performance bottleneck in (this implementation of) stringstreams if it takes that long! So I may just change my functions to accept an istream rather than a stringstream, so that I can pass the file directly for now, and if I can get the stringstream working in the future I can swap that in with a minimum of hassle.

But I''d still like to know how to do what I''ve been trying to do. Working around a problem is never satisfactory!

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.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!