4
$\begingroup$

What's the difference between a stream and a queue? They both have the concept of an ordered set of elements, but tend to have different implementations and a different vocabulary of 'insert'/'extract' (streams) vs. 'enqueue'/'dequeue' (queue). Are these interchangable? Do they suggest different concepts or patterns? If so, what are the differences?


Concrete example of 'stream insertion': https://www.cplusplus.com/reference/ostream/ostream/operator%3C%3C/


Potentially useful conceptual pieces?

$\endgroup$
2
  • $\begingroup$ Can you give us some concrete examples of streams in real programming languages and/or libraries? The only "streams" I can think of are the C and C++ I/O abstraction which don't have "insert/extract" but rather fread,fwrite and fseek which makes them more like weird extensible arrays than like queues. $\endgroup$ May 23, 2013 at 22:59
  • $\begingroup$ @WanderingLogic Thanks for writing--that's exactly the abstraction I'm referring to. If you look in the docs, I believe the standard '<<' and '>>' are called the 'stream insertion' and 'stream extraction' operators. cplusplus.com/reference/ostream/ostream/operator%3C%3C $\endgroup$
    – elliot42
    May 23, 2013 at 23:01

2 Answers 2

5
$\begingroup$

A queue is an abstract data type with two operations: enqueue() and dequeue() (or sometimes push() and pop()) that have first-in-first-out semantics.

A C stream is hard (for me) to describe abstractly. My best cut at it is that it is an abstraction representing a buffered file (where "file" is understood in the Unix sense of the word as something that is usually (but not always) a sequence of bytes and a current file position.)

At it's most general a stream is like a sequence of bytes numbered from 0, that can be arbitrarily extended at the end, but that has some additional state (the current position). There are some basic operations (fread() and fwrite()) that read or write an arbitrary number of bytes starting at the current position, and then reset the current position to point just after the most recently read or written byte. The current position can also be changed with fseek() and queried with ftell().

Now here's where it gets "icky." At the time a stream is opened a variety of factors determine which of the above operations are enabled or disabled. If you open your stream only for read then calling fwrite() will cause an error. If you open your stream only for write then calling fread() will cause an error. If your stream is actually a pipe or a socket, or is opened in mode append then you are not allowed to fseek(). You are only allowed to read or write from the current file position. stdin, stdout, and stderr are pipes so you can't fseek() them. You can't fwrite() stdin and you can't fread() stdout or stderr.

C++ fixed most of that mess by giving us a hierarchy of types (for example: http://www.cplusplus.com/reference/istream/basic_iostream/), so that we can do error recovery with RAII and can also tell whether the file is readable or writable by looking at the type (although I don't know offhand whether they fixed the seeking mess.)

But then there's the whole other question of formatted output. C has fprintf() which formats some stuff and puts some bytes into a writable stream (starting at the current file position). C++ replaced fprintf() with the (IMHO) really-much-too-cute operator<<(). operator<<() has the advantage of being strongly typed, but the extreme disadvantage of requiring the use of manipulators. So operator<<() puts some bytes to the output stream starting at the current file position, but formatted based on a whole bunch of state that is mutated by manipulators. So a C++ stream actually has a bunch of extra state that you need to know about. (Whether integers are going to get formatted hex or decimal from now on, how much precision floats are printed with, etc.)

So: a queue inserts and removes individual items of a well defined type from its front or its back. A stream is random access extendable array of bytes where you can read and write arbitrary numbers of bytes from the current file position (except when it isn't random access and except when you either can't read or can't write).

$\endgroup$
1
$\begingroup$

In a way, they are opposites.

A stream is something you read data from or write data to, indefinitely. Yes, a stream may be closed, but you don't know whether or when that will happen.

A stream is not an entity on your system that holds, or produces, or stores data. Rather, it is a gateway, a pipe, that can be attached to such an entity.

There is a strong tradition in Unix programming to be as agnostic as possible about what's attached to it. For instance, Unix utilities typically read from standard input and write to standard output, with as few assumptions as possible regarding what that input comes from or what that output goes to. The term stream suggests an input source or output sink treated like that.

A queue, on the other hand, is an entity in your system that holds data. It can be written to and can be read from, but it is not a stream, or a pair of streams; rather, it is something that streams can connect to. A queue acts as a buffer, holding the data written to it and releasing the data when read, in FIFO order.

To use a fairly flaky analogy: when comparing software to electrical circuits, a stream is like a connector (current can flow into it or out of it, and we don't know what's going to be at the other end) while a queue is like a capacitor.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.