If you use FRESH-LINE at the beginning of the second function, its output will always start on a new line, but if it's called right after the first, it won't emit an extra line break.
Several functions output Lisp data as s-expressions: PRINT prints an s-expression preceded by an end-of-line and followed by a space. PRIN1 prints just the s-expression. However, not all objects can be printed in a form that READ will understand.
When it's NIL , these functions will print the object in a special syntax that's guaranteed to cause READ to signal an error if it tries to read it; otherwise they will signal an error rather than print the object. I'll discuss some of the more important details of FORMAT , which essentially defines a mini-language for emitting formatted output, in Chapter To write binary data to a file, you have to OPEN the file with the same :element-type argument as you did to read it: ' unsigned-byte 8.
As anyone who has written code that deals with lots of files knows, it's important to close files when you're done with them, because file handles tend to be a scarce resource.
If you open files and don't close them, you'll soon discover you can't open any more files. For instance, you could always structure your file using code like this:. However, this approach suffers from two problems. One is simply that it's error prone--if you forget the CLOSE , the code will leak a file handle every time it runs. Or, as you'll see in Chapter 19, if any of the code before the CLOSE signals an error, control may jump out of the LET to an error handler and never come back to close the stream.
This is the basic form:. The forms in body-forms are evaluated with stream-var bound to a file stream opened by a call to OPEN with open-arguments as its arguments. Thus, you can write this to read a line from a file:.
In that case, you must take care to eventually close the stream yourself, or you'll leak file descriptors and may eventually end up unable to open any more files. So far you've used strings to represent filenames. However, using strings as filenames ties your code to a particular operating system and file system. To avoid this kind of nonportability, Common Lisp provides another representation of filenames: pathname objects.
Pathnames represent filenames in a structured way that makes them easy to manipulate without tying them to a particular filename syntax. And the burden of translating back and forth between strings in the local syntax--called namestrings --and pathnames is placed on the Lisp implementation. Unfortunately, as with many abstractions designed to hide the details of fundamentally different underlying systems, the pathname abstraction introduces its own complications.
When pathnames were designed, the set of file systems in general use was quite a bit more variegated than those in common use today. Consequently, some nooks and crannies of the pathname abstraction make little sense if all you're concerned about is representing Unix or Windows filenames. However, once you understand which parts of the pathname abstraction you can ignore as artifacts of pathnames' evolutionary history, they do provide a convenient way to manipulate filenames.
Most places a filename is called for, you can use either a namestring or a pathname. Which to use depends mostly on where the name originated.
Filenames provided by the user--for example, as arguments or as values in configuration files--will typically be namestrings, since the user knows what operating system they're running on and shouldn't be expected to care about the details of how Lisp represents filenames. But programmatically generated filenames will be pathnames because you can create them portably. A stream returned by OPEN also represents a filename, namely, the filename that was originally used to open the stream.
Together these three types are collectively referred to as pathname designators. All the built-in functions that expect a filename argument accept all three types of pathname designator. For instance, all the places in the previous section where you used a string to represent a filename, you could also have passed a pathname object or a stream.
The historical diversity of file systems in existence during the 70s and 80s can be easy to forget. Kent Pitman, one of the principal technical editors of the Common Lisp standard, described the situation once in comp.
If you look at the pathname abstraction from the point of view of any single file system, it seems baroque. However, if you take even two such similar file systems as Windows and Unix, you can already begin to see differences the pathname system can help abstract away--Windows filenames contain a drive letter, for instance, while Unix filenames don't.
The other advantage of having the pathname abstraction designed to handle the wide variety of file systems that existed in the past is that it's more likely to be able to handle file systems that may exist in the future. If, say, versioning file systems come back into vogue, Common Lisp will be ready. A pathname is a structured object that represents a filename using six components: host, device, directory, name, type, and version.
Most of these components take on atomic values, usually strings; only the directory component is further structured, containing a list of directory names as strings prefaced with the keyword :absolute or :relative. However, not all pathname components are needed on all platforms--this is one of the reasons pathnames strike many new Lispers as gratuitously complex.
On the other hand, you don't really need to worry about which components may or may not be used to represent names on a particular file system unless you need to create a new pathname object from scratch, which you'll almost never need to do.
Instead, you'll usually get hold of pathname objects either by letting the implementation parse a file system-specific namestring into a pathname object or by creating a new pathname that takes most of its components from an existing pathname. It takes a pathname designator and returns an equivalent pathname object. When the designator is already a pathname, it's simply returned. When it's a stream, the original filename is extracted and returned. When the designator is a namestring, however, it's parsed according to the local filename syntax.
The language standard, as a platform-neutral document, doesn't specify any particular mapping from namestring to pathname, but most implementations follow the same conventions on a given operating system. On Unix file systems, only the directory, name, and type components are typically used. On Windows, one more component--usually the device or host--holds the drive letter. On these platforms, a namestring is parsed by first splitting it into elements on the path separator--a slash on Unix and a slash or backslash on Windows.
The drive letter on Windows will be placed into either the device or the host component. All but the last of the other name elements are placed in a list starting with :absolute or :relative depending on whether the name ignoring the drive letter, if any began with a path separator. Autodesk does not warrant, either expressly or implied, the accuracy, reliability or completeness of the information translated by the machine translation service and will not be liable for damages or losses caused by the trust placed in the translation service.
Back to Topic Listing Previous Next. Filter by Lables. Message 1 of 5. Reading data from a text file into LISP. Anyone have an example of how to read data from a text file into string data for use in LISP that they could share?
Message 2 of 5. Message 3 of 5. Not sure exactly what you're looking for, but once a file is opened, each line you read with read-line comes in as a string: setq infile open "NameOfFile. Message 4 of 5. A file represents a sequence of bytes, does not matter if it is a text file or binary file. You can use the open function to create a new file or to open an existing file.
It is the most basic function for opening a file. However, the with-open-file is usually more convenient and more commonly used, as we will see later in this section. When a file is opened, a stream object is constructed to represent it in the LISP environment.
All operations on the stream are basically equivalent to operations on the file. The :if-exists argument specifies the action to be taken if the :direction is :output or :io and a file of the specified name already exists. If the direction is :input or :probe, this argument is ignored.
0コメント