;;; -*- Mode:gate; Fonts:(HL12 HL12I HL12B CPTFONTB HL12BI HL12B HL12I ) -*- =Node: Introduction =Text: 3INTRODUCTION* The Lisp Machine can access files on a variety of remote file servers, which are typically (but not necessarily) accessed through the Chaosnet, as well as accessing files on the Lisp Machine itself, if the machine has its own file system. You are not allowed to refer to files without first logging in, and you may also need to specify a username and password for the host on which the file is stored; see 4(MISCELL-2)Logging In*. The way to read or write a file's contents is to 1open* the file to get an input or output stream, use the standard stream I/O functions or operations described in chapters 4(IOSYSTEM-0)The I/O System* and 4(READPRINT-0)Expression Input and Output*, and then close the stream. The first section of this chapter tells how to open and close the stream. The rest of the chapter describes things specific to files such as deleting and renaming, finding out the true name of the file that has been opened, and listing a directory. Files are named with 1pathnames*. There is much to know about pathnames aside from accessing files with them; all this is described in the previous chapter. Many functions in this chapter take an argument called 1file* which is intended to specify a file to be operated on. This argument may be given as a pathname (which is defaulted), a namestring (which is parsed into a pathname and then defaulted), or a stream open to a file (the same file is used). =Node: 4Opening and Closing File Streams* =Text: 3OPENING AND CLOSING FILE STREAMS with-open-file* 1(stream* 1file* 1options...)* 1body...* 1Macro* Evaluates the 1body* forms with the variable 1stream* bound to a stream that reads or writes the file named by the value of 1file*. The 1options* forms evaluate to the file-opening options to be used; see 4(FILEACCESS-1)Opening and Closing File Streams*. When control leaves the body, either normally or abnormally (via 2throw*), the file is closed. If a new output file is being written and control leaves abnormally, the file is aborted and it is as if it were never written. Because it always closes the file, even when an error exit is taken, 2with-open-file* is preferred over 2open*. Opening a large number of files and forgetting to close them tends to break some remote file servers, ITS's for example. If an error occurs in opening the file, the result depends on the values of the 1error* option, the 1if-exists* option, and the 1if-does-not-exist* option. An error may be signaled (and possibly corrected with a new pathname), or 1stream* may be bound to a condition object or even 2nil*. 3with-open-file-case* 1(stream* 1file* 1options...)* 1clauses...* 1Macro* This opens and closes the file like 2with-open-file*, but what happens afterward is determined by 1clauses* that are like the clauses of a 2condition-case* (4(DEBUGGING-1)Handling Conditions*). Each clause begins with a condition name or a list of condition names and is executed if 2open* signals a condition that possesses any of those names. A clause beginning with the symbol 2:no-error* is executed if the file is opened successfully. This would be where the reading or writing of the file would be done. Example: 3(with-open-file-case (stream (send generic-pathname* 3 :source-pathname))* 3 (sys:remote-network-error (format t "~&Host down."))* 3 (fs:file-not-found (format t "~&(New file)"))* 3 (:no-error (setq list (read stream)))) file-retry-new-pathname* 1(pathname-var* 1condition-names...)* 1body...* 1Macro* 3file-retry-new-pathname-if* 1cond-form* 1(pathname-var* 1condition-names...)* 1body...* 2file-retry-new-pathname* executes 1body*. If 1body* does not signal any of the conditions in 1condition-names*, 1body*'s values are simply returned. If any of 1condition-names* is signaled, 2file-retry-new-pathname* reads a new pathname, 2setq*'s 1pathname-var* to it, and executes 1body* again. The user can type 2End* instead of a pathname if he wishes to let the condition be handled by the debugger. 2file-retry-new-pathname-if* is similar, but the conditions are handled only if 1cond-form*'s value is non-2nil*. For an example, see the example of the following macro. 3with-open-file-retry* 1(stream* 1(pathname-var* 1condition-names...)* 1options...)* 1body...* 1Macro* Like 2with-open-file* inside of a 2file-retry-new-pathname*. If an error occurs while opening the file and it has one of the specified 1condition-names*, a new pathname is read, the variable 1pathname-var* is 2setq*'d to it, and another attempt is made to open a file with the newly specified name. Example: 3(with-open-file-retry (instream (infile fs:file-not-found))* 3 ...)* 2infile* should be a variable whose value is a pathname or namestring. The example is equivalent to 3(file-retry-new-pathname (infile fs:file-not-found)* 3 (with-open-file (instream infile)* 3 ...)) with-open-file-search* 1Macro* Opens a file, trying various pathnames until one of them succeeds. The pathnames tried differ only in their type components. For example, 2load* uses this macro to search for either a compiled file or a source file. The calling sequence looks like 3(with-open-file-search* 3 (1streamvar* (1operation* 1defaults* 1auto-retry*)* 3 1types-and-pathname* 1options*...)* 3 1body*...)* 2with-open-file-search* tries opening various files until one succeeds; then binds 1streamvar* to the stream and executes 1body*, closing the stream on exit. The values of 1body* are returned. 1types-and-pathname* specifies which files to open. It should be a form which evaluates to two values, the first being a list of types to try and the second being a pathname called the base pathname. Each pathname to try is made by merging the base pathname with the defaults 1defaults* and one of the types. The types may be strings or canonical type keywords (see 4(FILENAMES-1)Canonical Types*). 1options* are forms whose values should be alternating to keywords and values, which are passed to 2open* each time. If all the names to be tried fail, a 2fs:multiple-file-not-found* error is signaled. 1operation* is provided just so that the 2:operation* operation on the condition object can return it. Usually the value given for 1operation* should be the user-level function for which the 2with-open-file-search* is being done. If 1auto-retry* is non-2nil*, an error causes the user to be prompted for a new base pathname. The entire set of types specified is tried anew with the new pathname. 3open* 1file* &rest 1options* Returns a stream that is connected to the specified file. Unlike Maclisp, the 2open* function creates streams only for 1files*; streams of other kinds are created by other functions. The 1file* and 1options* arguments are the same as in 2with-open-file*; see above. When the caller is finished with the stream, it should close the file by using the 2:close* operation or the 2close* function. The 2with-open-file* special form does this automatically and so is usually preferred. 2open* should only be used when the control structure of the program necessitates opening and closing of a file in some way more complex than the simple way provided by 2with-open-file*. Any program that uses 2open* should set up 2unwind-protect* handlers (see 4(FLOWCTL-2)Dynamic Non-Local Exits*) to close its files in the event of an abnormal exit. 3close* 1stream* &optional 1option* The 2close* function simply sends the 2:close* message to 1stream*. If 1option* is 2:abort* for a file output stream, the file is discarded. 3cli:close* 1stream* &key 1abort* The Common Lisp version of 2close* is the same as 2close* except for its calling convention. If 1abort* is non-2nil* for a file output stream, the file is discarded. 3fs:close-all-files* Closes all open files. This is useful when a program has run wild opening files and not closing them. It closes all the files in 2:abort* mode (see 4(IOSYSTEM-2)Standard Output Stream Operations*), which means that files open for output are deleted. Using this function is dangerous, because you may close files out from under various programs like Zmacs and ZMail; only use it if you have to and if you feel that you know what you're doing. The 1options* used when opening a file are normally alternating keywords and values, like any other function that takes keyword arguments. In addition, for compatibility with the Maclisp 2open* function, if only a single option is specified it is either a keyword or a list of keywords (not alternating with values). The file-opening options control things like whether the stream is for input from a existing file or output to a new file, whether the file is text or binary, etc. The following keyword arguments are standardly recognized; additional keywords can be implemented by particular file system hosts. 1direction* Controls which direction of I/O can be done on the resulting stream. The possible values are 2:input* (the default), 2:output*, 2nil*, 2:probe*, 2:probe-directory* and 2:probe-link*. The first two should be self-explanatory. 2nil* or 2:probe* means that this is a ``probe'' opening; no data are to be transferred, the file is being opened only to verify its existence or access its properties. The stream created in this case does not permit any I/O. 2nil* and 2:probe* differ in causing different defaults for the argument 1if-does-not-exist*. If that argument is specified explicitly, 2nil* and 2:probe* are equivalent. 2:probe-directory* is used to see whether a directory exists. If the directory specified for the file to be opened is found, then the 2open* completes (returning a non-I/O stream) as if the specified file existed whether it really exists or not. 2:probe-link* is used to find out the truename of a link. If the file specified exists as a link, then the 2open* completes returning a non-I/O stream which describes the link itself rather than the file linked to. If the file exists and is not a link, the 2open* also completes for it as with any probe. Common Lisp defines the value 2:io* for this argument, requesting a stream that can do input and output, but no file system supported by the Lisp Machine has this capability. 1characters* The possible values are 2t* (the default), 2nil*, which means that the file is a binary file, and 2:default*, which means that the file system should decide whether the file contains characters or binary data and open it in the appropriate mode. 1byte-size* The possible values are 2nil* (the default), a number, which is the number of bits per byte, and 2:default*, which means that the file system should choose the byte size based on attributes of the file. If the file is being opened as characters, 2nil* selects the appropriate system-dependent byte size for text files; it is usually not useful to use a different byte size. If the file is being opened as binary, 2nil* selects the default byte size of 16 bits. 1element-type* This is the Common Lisp way to specify what kind of objects the stream wants to read or write. This combines the effect of the 1characters* and 1byte-size* arguments. The value is a type specifier; it must be one of the following: 2string-char* Read or write characters as usual. The default. 2character* Read or write characters, dealing with characters that are more than 8 bits. You can succeed in writing out any sequence of character objects and reading it back, but the file does not look anything like a text file. 2(unsigned-byte 1n*)* Read or write 1n*-bit bytes. Like 1characters* = 2nil*, 1byte-size* = 1n*. 2unsigned-byte* Similar, but uses the byte size that the file was originally written with. This is the same as 1characters* = 2nil*, 1byte-size* = 2:default*. 2(signed-byte 1n*)* Read or write 1n*-bit bytes, sign-extending on input. Each byte read from the file is sign-extended so that its most significant bit serves as a sign bit. 2signed-byte* Similar, but uses the byte size that the file was originally written with. 2(mod 1n*)* Like 2unsigned-byte* for a big enough byte size to hold all numbers less than 1n*. 2bit* is also accepted, and means 2(mod 2)*. 2:default* Is allowed, even though it is not a type specifier. It is the same as using 2:default* as the value of 1characters*. 1if-exists* For output opens, 1if-exists* specifies what to do if a file with the specified name already exists. There are several values you can use: 2:new-version* Create a new version. This makes sense only when the pathname has 2:newest* as its version, and it is the default in that case. 2:supersede* Make a new file which, when closed, replaces the old one. 2:overwrite* Write over the data of the existing file, starting at the beginning, and set the file's length to the length of the newly written data. 2:truncate* Like 2:overwrite* except that it discards the old contents of the file immediately, making it empty except for what is written into it this time. 2:append* Add new data onto the existing file at the end. 2:rename* Rename the existing file and then create a new one. 2:rename-and-delete* Rename the existing file, create a new one, and delete the old file when the new one is closed. 2:error* Signal an error (2fs:file-already-exists*). This is the default when the pathname's version is not 2:newest*. The further handling of the error is controlled by the 1error* argument. 2nil* Return 2nil* from 2open* in this case. The 1error* argument is irrelevant in this case. 1if-does-not-exist* Specifies what to do when the file requested does not exist. There are three allowed values: 2:create* Create a file. This is the default for output opens, except when 1if-exists* is 2:append*, 2:overwrite* or 2:truncate*. This silly exception is part of the Common Lisp specifications. 2:error* Signal an error. This is the default for input opens, and also for output opens when 1if-exists* is 2:append*, 2:overwrite* or 2:truncate*. The further handling of the error is controlled by the 1error* argument. 2nil* Return 2nil* from 2open*. This is the default for 2:probe* opens. The 1error* argument is irrelevant in this case. 1error* Specifies what to do if an error is signaled for any reason. (Note that the values of the 1if-exists* and 1if-does-not-exist* arguments control whether an error is signaled in certain circumstances.) The possible values are 2t* (the default), 2:reprompt* and 2nil*. 2t* means that nothing special is done, so the error invokes the debugger if the caller does not handle it. 2nil* means that the condition object should be returned as the value of 2open*. 2:reprompt* means that a new file name should be read and opened. Any caller which need not know reliably which file was ultimately opened might as well specify 2:reprompt* for this argument. Callers which need to know if a different file is substituted should never specify 2:reprompt*; they may use 2with-open-file-retry* or 2file-retry-new-pathname* (see 4(FILEACCESS-1)Opening and Closing File Streams*) if they wish to permit an alternative file name to be substituted. 1:submit* If specified as 2t* when opening a file for output, the file is submitted as a batch job if it is closed normally. The default is 2nil*. You must specify 2:direction* 2:output* as well. 1deleted* The default is 2nil*. If 2t* is specified, and the file system has the concept of deleted but not expunged files, it is possible to open a deleted file. Otherwise deleted files are invisible. 1temporary* If 2t* is specified, the file is marked as temporary, if the file system has that concept. The default is 2nil*. 1preserve-dates* If 2t* is specified, the file's reference and modification dates are not updated. The default is 2nil*. 1flavor* This controls the kind of file to be opened. The default is 2nil*, a normal file. Other possible values are 2:directory* and 2:link*. Only certain file systems recognize this keyword. 1link-to* When creating a file with 1flavor* 2:link*, this argument must be specified; its value is a pathname or namestring that becomes the target of the link. 1submit* The value can be either 2nil* (the default) or 2t*. If the value is 2t*, and the 2:direction* is 2:output*, the resulting file will be submitted as a batch job. Currently, this option is implemented only for Twenex and VMS. 1estimated-size* The value may be 2nil* (the default), which means there is no estimated size, or a number of bytes. Some file systems use this to optimize disk allocation. 1physical-volume* The value may be 2nil* (the default), or a string that is the name of a physical volume on which the file is to be stored. This is not meaningful for all file systems. 1logical-volume* The value may be 2nil* (the default), or a string that is the name of a logical volume on which the file is to be stored. This is not meaningful for all file systems. 1super-image* The value may be 2nil* (the default), or 2t*, which disables the special treatment of rubout in ASCII files. Normally, rubout is an escape which causes the following character to be interpreted specially, allowing all characters from 0 through 376 (octal) to be stored. This applies to ASCII file servers only. 1raw* The value may be 2nil* (the default), or 2t*, which disables all character set translation in ASCII files. This applies to ASCII file servers only. In the Maclisp compatibility mode, there is only one 1option*, and it is either a symbol or a list of symbols. These symbols are recognized no matter what package they are in, since Maclisp does not have packages. The following symbols are recognized: 2in, read* Select opening for input (the default). 2out, write, print* Select opening for output; a new file is to be created. 2binary, fixnum* Select binary mode; otherwise character mode is used. Note that fixnum mode uses 16-bit binary words and is not compatible with Maclisp fixnum mode, which uses 36-bit words. On the PDP-10, fixnum files are stored with two 16-bit words per PDP-10 word, left-justified and in PDP-10 byte order. 2character, ascii* The opposite of fixnum. This is the default. 2single, block* Ignored for compatibility with the Maclisp 2open* function. 2byte-size* Must be followed by a number in the options list, and must be used in combination with 2fixnum*. The number is the number of bits per byte, which can be from 1 to 16. On a PDP-10 file server these bytes will be packed into words in the standard way defined by the 2ILDB* instruction. The 2:tyi* stream operation will (of course) return the bytes one at a time. 2probe, error, noerror, raw, super-image, deleted, temporary* These are not available in Maclisp. The corresponding keywords in the normal form of file-opening options are preferred over these. =Node: 4File Stream Operations* =Text: 3FILE STREAM OPERATIONS* The following functions and operations may be used on file streams, in addition to the normal I/O operations which work on all streams. Note that several of these operations are useful with file streams that have been closed. Some operations use pathnames; refer to 4(FILENAMES-0)Naming of Files* for an explanation of pathnames. 3file-length* 1file-stream* Returns the length of the file open on 1file-stream*, in terms of the units in which I/O is being done on that stream. (A stream is needed, rather than just a pathname, in order to specify the units.) 3file-position* 1file-stream* &optional 1new-position* With one argument, returns the current position in the file of 1file-stream*, using the 2:read-pointer* stream operation. It may return 2nil* meaning that the position cannot be determined. In fact, it always returns 2nil* for a stream open in character mode and not at the beginning of the file. With two arguments, sets the position using the 2:set-pointer* stream operation, if possible, and returns 2t* if the setting was possible and 2nil* if not. You can specify 2:start* as the 1new-position* to position to the beginning of the file, or 2:end* to position to the end. 3:pathname* 1Operation on file streams* Returns the pathname that was opened to get this stream. This may not be identical to the argument to 2open*, since missing components will have been filled in from defaults. The pathname may have been replaced wholesale if an error occurred in the attempt to open the original pathname. 3:truename* 1Operation on file streams* Returns the pathname of the file actually open on this stream. This can be different from what 2:pathname* returns because of file links, logical devices, mapping of version 2:newest* to a particular version number, etc. For an output stream the truename is not meaningful until after the stream has been closed, at least when the file server is an ITS. 3:generic-pathname* 1Operation on file streams* Returns the generic pathname of the pathname that was opened to get this stream. Normally this is the same as the result of sending the 2:generic-pathname* message to the value of the 2:pathname* operation on the stream; however, it does special things when the Lisp system is bootstrapping itself. 3:qfaslp* 1Operation on file streams* Returns 2t* if the file has a magic flag at the front that says it is a QFASL file, 2nil* if it is an ordinary file. 3:length* 1Operation on file streams* Returns the length of the file, in bytes or characters. For text files on ASCII file servers, this is the number of ASCII characters, not Lisp Machine characters. The numbers are different because of character-set translation; see 4(FILEACCESS-4)File Servers* for a full explanation. For an output stream the length is not meaningful until after the stream has been closed, at least when the file server is an ITS. 3:creation-date* 1Operation on file streams* Returns the creation date of the file, as a number that is a universal time. See the chapter on the time package (4(DATETIME-0)Dates and Times*). 3:info* 1Operation on file streams* Returns a cons of the file's truename and its creation date. This can be used to tell if the file has been modified between two 2open*'s. For an output stream the information is not guaranteed to be correct until after the stream has been closed. 3:properties* &optional 1(error-p* 3t1)** 1Operation on file streams* This returns two values: a property list (like an element of the list returned by 2fs:directory-list*), and a list of the settable properties. See the section on standard file properties (4(FILEACCESS-3)Accessing Directories*) for a description of the ones that may possible found in the list. 3:set-byte-size* 1new-byte-size* 1Operation on file streams* This is only allowed on binary file streams. The byte size can be changed to any number of bits from 1 to 16. 3:delete* &optional 1(error-p* 3t1)** 1Operation on file streams* Deletes the file open on this stream. For the meaning of 1error-p*, see the 2deletef* function. The file doesn't really go away until the stream is closed. 3:undelete* &optional 1(error-p* 3t1)** 1Operation on file streams* If you have used the 2:deleted* option in 2open* to open a deleted file, this operation undeletes the file. 3:rename* 1new-name* &optional 1(error-p* 3t1)** 1Operation on file streams* Renames the file open on this stream. For the meaning of 1error-p*, see the 2renamef* function. File output streams implement the 2:finish* and 2:force-output* operations.