Skip to main content

Chapter 14: I/O: Streams and Files

  • Chapter
Common Lisp Recipes
  • 2028 Accesses

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.

This is a preview of subscription content, log in via an institution to check access.

Access this chapter

Chapter
USD 29.95
Price excludes VAT (USA)
  • Available as PDF
  • Read on any device
  • Instant download
  • Own it forever
eBook
USD 79.99
Price excludes VAT (USA)
  • Available as EPUB and PDF
  • Read on any device
  • Instant download
  • Own it forever
Softcover Book
USD 99.99
Price excludes VAT (USA)
  • Compact, lightweight edition
  • Dispatched in 3 to 5 business days
  • Free shipping worldwide - see info

Tax calculation will be finalised at checkout

Purchases are for personal use only

Institutional subscriptions

Notes

  1. 1.

    This is in a way similar to I/O redirection on Unix, but there are also significant differences.

  2. 2.

    See Recipe 14-7.

  3. 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. 4.

    See Chapter 6 of Practical Common Lisp ( http://www.gigamonkeys.com/book/variables.html ).

  5. 5.

    See also Recipe 14-7.

  6. 6.

    See Recipe 4-4 for *PRINT-BASE*.

  7. 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. 8.

    And, of course, it can’t be any stream, but the stream has to be associated with a file.

  9. 9.

    This means that even without the :ELEMENT-TYPE part, our code from above should have yielded the same result.

  10. 10.

    See also Recipe 14-10

  11. 11.

    Try it. Replace MAKE-ARRAY with MAKE-LIST in our example above.

  12. 12.

    Or see the example with #∖Newline in Recipe 14-12.

  13. 13.

    Using UNWIND-PROTECT; see Recipe 12-8.

  14. 14.

    See Recipe 14-9.

  15. 15.

    Use "NUL:" on Windows.

  16. 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. 17.

    To be more precise, it only has to be adjustable if you’re trying to write past the end of the string.

  18. 18.

    If you’ve already worked with Java’s StringWriter and StringReader, you’re used to this idea.

  19. 19.

    See Recipe 10-8.

  20. 20.

    See also Recipe 14-10.

  21. 21.

    These two functions can also be used with character streams. See Recipe 14-4 for an example.

  22. 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. 23.

    See http://en.wikipedia.org/wiki/Data_structure_alignment .

  24. 24.

    Which can be done with Quicklisp; see Recipe 18-2.

  25. 25.

    See Recipe 9-8.

  26. 26.

    See http://en.wikipedia.org/wiki/Endianness#Floating-point_and_endianness .

  27. 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. 28.

    As usual, positions start at 0.

  29. 29.

    Where’s that from?

  30. 30.

    See Recipe 14-4 for FILE-AT-ONCE.

  31. 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. 32.

    See also Recipe 9-1.

  33. 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. 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. 35.

    But we can—let’s say we’re concerned about performance—implement our own version of READ-SEQUENCE. See below.

  36. 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. 37.

    To be found at http://www.nhplace.com/kent/CL/Issues/stream-definition-by-user.html .

  38. 38.

    The part about Gray streams is at http://www.lispworks.com/documentation/lw70/LW/html/lw-175.htm .

Author information

Authors and Affiliations

Authors

Electronic Supplementary Material

Below is the link to the electronic supplementary material.

chapter-14 (zip 5 kb)

Rights and permissions

Reprints 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

Publish with us

Policies and ethics