Portable stream-of-bytes interface for C++
I work on an open source portable C++ image compression library. Currently, my API works by exchanging pointers to byte arrays with image data. I would like to support some kind of streaming mode for better performance and memory consumption.
For this, I would like to know if there is an in开发者_如何学Cterface or abstract base class (part of the C++ standard libraries) that I can use as an interface to a stream of input bytes, similar to Java's InputStream, or C# Stream. It could be as simple as this:
class inputstream
{
public:
virtual void readbytes(char*, size_t count) = 0;
};
I could define an interface like this myself, but then I require everybody to implement some kind of adapter to interface to my code, and my flavor of IO error handling, and I would like to avoid that.
Ideally this interface or base class would be already implemented by some existing C++ standard libraries for reading files. If it is not a base class, it should be totally abstract so my users can connect to whatever bytestream they have (platform specific, socket, whatever). I have browsed around in iostream but found nothing that fits the bill. It should be as light weight as possible: Error handling should be defined, but there's no need for seeking the stream.
If there is no such thing (which I fear), is there something like an existing best practice? Like a function pointer with a standard signature, and a contract for error handling? If there are creative solutions that would work in C as well, I am also interested.
Edit: the key thing is that base class's read() method(s) are virtual.
If your library accepts a std::istream
then it will work with files, memory buffers, and user-defined streams.
Your source of confusion seems to be that istream
doesn't have any virtual members to override and customize. This is because istream
delegates all customizable functionality to std::streambuf
, which is where you'll find the virtual members.
If you wanted to expose the compression results as a stream, you'd want to derive from streambuf
. Conversely, you could accept an istream
to read from and an ostream
to store compressed results into.
By accepting an istream
, your client can supply an istream
constructed on any streambuf
, either the library provided stringbuf
or filebuf
or a custom version.
Since you don't want to work with textual data but byte streams, perhaps using the streambuf
directly would be better than using istream
to wrap it.
Look at stringstream. It does what you need
You can use the plain std::ifstream
, which is nothing more than a "stream of bytes". Byte extraction is by default byte per byte, and can be used in a kazillion number of different ways:
#include <fstream>
using std::ifstream;
int main()
{
ifstream stream;
stream.open("example.jpg", ifstream::binary ); // open raw binary stream
if( !stream ) // check if stream is ready to be read
throw runtime_error( "Failed to open file..." );
char byteBuffer;
while( stream >> byteBuffer ) // read all bytes until read/extraction fails
{
// do something with the byte
}
stream.close();
return 0;
}
I hope this helps. I understand not every platform has a byte-size char, but I'm sure there's some trick that allows you to use a byte-element iostream object (default is char
or wchar_t
for the wide classes).
std::fstream sounds like it fits the bill, despite your feeling of its lack of appropriateness, perfectly to me. Sure it has a seek but its not exactly heavy code.
精彩评论