Advertisement

Binary Streams

Started by April 21, 2000 08:35 PM
5 comments, last by Kylotan 24 years, 7 months ago
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
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
Advertisement
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
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
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 datastringstream fileBuffer;ifstream file(filename2.c_str(), ios::binary/ios::in);// Method 2.// Find file sizeint filesize;file.seekg(0, ios::end); // move to end of filefilesize = 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 datachar* buffer = new char[filesize];// Fill it from filetheApp.LogMsg("About to read in buffer.");file.read(buffer, filesize);// Fill the stringstream with ittheApp.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?
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
[email=jperegrine@customcall.com]ColdfireV[/email]
Advertisement
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!

This topic is closed to new replies.

Advertisement