Abstract
Communication between Common Lisp and the “world outside” is usually performed via streams, whether you are interacting with files, with network connections, or with your IDE. These streams, which can be character streams (for textual data of all kinds) or binary streams (to transfer bits in chunks of bytes), are conceptually easy to use but still remarkably flexible and they are ultimately also used by the Lisp reader (see Chapter 8) and the Lisp printer (see Chapter 9). This chapter is about the various ways you can use, adapt, and combine streams and it ends with a recipe that demonstrates how you can create your own stream classes for almost every task you can imagine.
Access this chapter
Tax calculation will be finalised at checkout
Purchases are for personal use only
Notes
- 1.
This is in a way similar to I/O redirection on Unix, but there are also significant differences.
- 2.
See Recipe 14-7.
- 3.
Note that READ (see Recipe 8-1) can, of course, read data from any stream but if used with no arguments, like here, will read from *STANDARD-INPUT*.
- 4.
See Chapter 6 of Practical Common Lisp ( http://www.gigamonkeys.com/book/variables.html ).
- 5.
See also Recipe 14-7.
- 6.
See Recipe 4-4 for *PRINT-BASE*.
- 7.
One situation where it could make sense to call FINISH-OUTPUT is before closing a stream. On some implementations, errors occurring when the stream is flushed implicitly due to CLOSE might not be reported (but will be reported if you flush explicitly).
- 8.
And, of course, it can’t be any stream, but the stream has to be associated with a file.
- 9.
This means that even without the :ELEMENT-TYPE part, our code from above should have yielded the same result.
- 10.
See also Recipe 14-10
- 11.
Try it. Replace MAKE-ARRAY with MAKE-LIST in our example above.
- 12.
Or see the example with #∖Newline in Recipe 14-12.
- 13.
Using UNWIND-PROTECT; see Recipe 12-8.
- 14.
See Recipe 14-9.
- 15.
Use "NUL:" on Windows.
- 16.
This is similar but not identical. Writing to something like /dev/null is a system-level feature, while what we’re doing here works at the language level. You could also, from within Common Lisp, really open a stream to /dev/null, but it’d be slower.
- 17.
To be more precise, it only has to be adjustable if you’re trying to write past the end of the string.
- 18.
If you’ve already worked with Java’s StringWriter and StringReader, you’re used to this idea.
- 19.
See Recipe 10-8.
- 20.
See also Recipe 14-10.
- 21.
These two functions can also be used with character streams. See Recipe 14-4 for an example.
- 22.
Should you ever need to be able to read or write bytes of arbitrary sizes (possibly at the cost of speed), have a look at the odd-streams library.
- 23.
- 24.
Which can be done with Quicklisp; see Recipe 18-2.
- 25.
See Recipe 9-8.
- 26.
- 27.
Sounds kind of ugly and pretty C-like, but might be necessary if you’re dealing with data where the layout is implicitly specified by a foreign language (as opposed to clearly defined).
- 28.
As usual, positions start at 0.
- 29.
Where’s that from?
- 30.
See Recipe 14-4 for FILE-AT-ONCE.
- 31.
Structures defined by DEFSTRUCT will usually be printed in a default way such that they can be read back in (but only, of course, if the corresponding structure type is defined before the object is read). But you can override this behavior and use your own print methods for your structures; see the HyperSpec’s dictionary entry for DEFSTRUCT.
- 32.
See also Recipe 9-1.
- 33.
As the name says, this function only works with EQL hash tables. It has several other design flaws as well and it should not be used in production code. The only reason for its existence is to get the general idea across.
- 34.
A much more elaborate version of this behavior is exhibited by the in-memory streams found in the flexi-streams library; see Recipe 3-3.
- 35.
But we can—let’s say we’re concerned about performance—implement our own version of READ-SEQUENCE. See below.
- 36.
But you should probably implement more than the required minimum or your Gray streams could end up being pretty slow compared to “normal” streams. As usual, there’s a price you have to pay for flexibility and if speed is important, you might want to profile (see Recipe 17-2) your Gray streams or check for vendor-specific alternatives, like, for example, AllegroCL’s “simple streams.”
- 37.
To be found at http://www.nhplace.com/kent/CL/Issues/stream-definition-by-user.html .
- 38.
The part about Gray streams is at http://www.lispworks.com/documentation/lw70/LW/html/lw-175.htm .
Author information
Authors and Affiliations
Electronic Supplementary Material
Below is the link to the electronic supplementary material.
Rights and permissions
Copyright information
© 2016 Edmund Weitz
About this chapter
Cite this chapter
Weitz, E. (2016). Chapter 14: I/O: Streams and Files. In: Common Lisp Recipes. Apress, Berkeley, CA. https://doi.org/10.1007/978-1-4842-1176-2_14
Download citation
DOI: https://doi.org/10.1007/978-1-4842-1176-2_14
Publisher Name: Apress, Berkeley, CA
Print ISBN: 978-1-4842-1177-9
Online ISBN: 978-1-4842-1176-2
eBook Packages: Professional and Applied ComputingApress Access BooksProfessional and Applied Computing (R0)