

@node Files, Streams, Filenames, Top
@chapter Files

@menu
* File System Concepts::	
* Files Dictionary::		
@end menu

@node File System Concepts, Files Dictionary, Files, Files
@section File System Concepts

@c including concept-files

This section describes the @r{Common Lisp} interface to file systems.
The model used by this interface assumes 
     that @i{files}
@IGindex{file}
 are named by @i{filenames}
@IGindex{filename}
,
     that a @i{filename} can be represented by a @i{pathname} @i{object}, 
 and that given a @i{pathname} a @i{stream}
@IGindex{stream}
 can be constructed 
      that connects to a @i{file} whose @i{filename} it represents.

For information about opening and closing @i{files},
and manipulating their contents, see @ref{Streams}.

Figure 20--1 lists some @i{operators} 
that are applicable to @i{files} and directories.

@group
@noindent
@w{  compile-file  file-length      open            }
@w{  delete-file   file-position    probe-file      }
@w{  directory     file-write-date  rename-file     }
@w{  file-author   load             with-open-file  }

@noindent
@w{    Figure 20--1: File and Directory Operations  }

@end group

@menu
* Coercion of Streams to Pathnames::  
* File Operations on Open and Closed Streams::	
* Truenames::			
@end menu

@node Coercion of Streams to Pathnames, File Operations on Open and Closed Streams, File System Concepts, File System Concepts
@subsection Coercion of Streams to Pathnames

A @i{stream associated with a file}
@IGindex{stream associated with a file}
 is either a @i{file stream}
or a @i{synonym stream} whose target is a @i{stream associated with a file}
@IGindex{stream associated with a file}
.
Such streams can be used as @i{pathname designators}.

Normally, when a @i{stream associated with a file} is used as a
@i{pathname designator}, it denotes the @i{pathname} used to 
open the @i{file}; this may be, but is not required to be, the
actual name of the @i{file}.

Some functions, such as @b{truename} and @b{delete-file},
coerce @i{streams} to @i{pathnames} in a different way that 
involves referring to the actual @i{file} that is open, which might
or might not be the file whose name was opened originally.  Such special
situations are always notated specifically and are not the default.

@node File Operations on Open and Closed Streams, Truenames, Coercion of Streams to Pathnames, File System Concepts
@subsection File Operations on Open and Closed Streams

Many @i{functions} that perform @i{file} operations accept either
@i{open} or @i{closed} @i{streams} as @i{arguments};
see @ref{Stream Arguments to Standardized Functions}.

Of these, the @i{functions} in Figure 20--2 treat @i{open} and 
@i{closed} @i{streams} differently.

@group
@noindent
@w{  delete-file  file-author      probe-file  }
@w{  directory    file-write-date  truename    }

@noindent
@w{  Figure 20--2: File Functions that Treat Open and Closed Streams Differently}

@end group

Since treatment of @i{open} @i{streams} by the @i{file system} 
may vary considerably between @i{implementations}, however, 
a @i{closed} @i{stream} might be the most reliable kind of
@i{argument} for some of these functions---in particular, those in
Figure 20--3.  For example, in some @i{file systems}, 
@i{open} @i{files} are written under temporary names 
and not renamed until @i{closed}
and/or are held invisible until @i{closed}.
In general, any code that is intended to be portable should
use such @i{functions} carefully.

@group
@noindent
@w{  directory  probe-file  truename  }

@noindent
@w{  Figure 20--3: File Functions where Closed Streams Might Work Best}

@end group

@node Truenames,  , File Operations on Open and Closed Streams, File System Concepts
@subsection Truenames

Many @i{file systems} permit more than one @i{filename} to designate 
a particular @i{file}.

Even where multiple names are possible, most @i{file systems} have a convention
for generating a canonical @i{filename} in such situations.  Such a canonical
@i{filename} (or the @i{pathname} representing such a @i{filename}) is
called a @i{truename}
@IGindex{truename}
.  

The @i{truename} of a @i{file} may differ from other @i{filenames}
for the file because of
     symbolic links,
     version numbers,
     logical device translations in the @i{file system},
     @i{logical pathname} translations within @r{Common Lisp},
  or other artifacts of the @i{file system}.

The @i{truename} for a @i{file} is often, but not necessarily, unique for
each @i{file}.  For instance, a Unix @i{file} with multiple hard links 
could have several @i{truenames}.

@menu
* Examples of Truenames::	
@end menu

@node Examples of Truenames,  , Truenames, Truenames
@subsubsection Examples of Truenames

For example, a DEC TOPS-20 system with @i{files} @t{PS:<JOE>FOO.TXT.1} 
and @t{PS:<JOE>FOO.TXT.2} might permit the second @i{file} to be referred
to as @t{PS:<JOE>FOO.TXT.0}, since the ``@t{.0}'' notation denotes ``newest''
version of several @i{files}.
In the same @i{file system}, a ``logical device'' ``@t{JOE:}'' might be 
taken to refer to @t{PS:<JOE>}'' and so the names @t{JOE:FOO.TXT.2} or
@t{JOE:FOO.TXT.0} might refer to @t{PS:<JOE>FOO.TXT.2}.
In all of these cases, the @i{truename} of the file would probably be
@t{PS:<JOE>FOO.TXT.2}.

If a @i{file} is a symbolic link to another @i{file} (in a @i{file system}
permitting such a thing), it is conventional for the @i{truename} to be
the canonical name of the @i{file} after any symbolic links have been followed;
that is, it is the canonical name of the @i{file} whose contents would
become available if an @i{input} @i{stream} to that @i{file} were 
opened.

In the case of a @i{file} still being created (that is, of an @i{output}
@i{stream} open to such a @i{file}), the exact @i{truename} of the file
might not be known until the @i{stream} is closed.  In this case, 
the @i{function} @b{truename} might return different values for such a @i{stream}
before and after it was closed.  In fact, before it is closed, the name returned
might not even be a valid name in the @i{file system}---for example, while a
file is being written, it might have version @t{:newest} and might only take on 
a specific numeric value later when the file is closed even in a @i{file system}
where all files have numeric versions.

@c end of including concept-files

@node Files Dictionary,  , File System Concepts, Files
@section Files Dictionary

@c including dict-files

@menu
* directory::			
* probe-file::			
* ensure-directories-exist::	
* truename::			
* file-author::			
* file-write-date::		
* rename-file::			
* delete-file::			
* file-error::			
* file-error-pathname::		
@end menu

@node directory, probe-file, Files Dictionary, Files Dictionary
@subsection directory                                                        [Function]

@code{directory}  @i{pathspec {&key}} @result{}  @i{pathnames}

@subsubheading  Arguments and Values::

@i{pathspec}---a @i{pathname designator},
		   which may contain @i{wild} components.

@i{pathnames}---a @i{list} of

@i{physical pathnames}.

@subsubheading  Description::

Determines which, if any, @i{files} that are present
in the file system have names matching @i{pathspec},
and returns a 

@i{fresh}

@i{list} of @i{pathnames} corresponding to the @i{truenames} of
those @i{files}.

An @i{implementation} may be extended to accept 
@i{implementation-defined} keyword arguments to @b{directory}.  

@subsubheading  Affected By::

The host computer's file system.

@subsubheading  Exceptional Situations::

If the attempt to obtain a directory listing is not successful,
an error of @i{type} @b{file-error} is signaled.

@subsubheading  See Also::

@b{pathname},

@b{logical-pathname},

@ref{ensure-directories-exist}
,
@ref{File System Concepts},
@ref{File Operations on Open and Closed Streams},

@ref{Pathnames as Filenames}

@subsubheading  Notes::

If the @i{pathspec} is not @i{wild},
the resulting list will contain either zero or one elements.

@r{Common Lisp} specifies ``{&key}'' in the argument list to @b{directory} 
even though no @i{standardized} keyword arguments to @b{directory} are defined.
``@t{:allow-other-keys t}''
may be used in @i{conforming programs} in order to quietly ignore any
additional keywords which are passed by the program but not supported
by the @i{implementation}.

@node probe-file, ensure-directories-exist, directory, Files Dictionary
@subsection probe-file                                                       [Function]

@code{probe-file}  @i{pathspec} @result{}  @i{truename}

@subsubheading  Arguments and Values::

@i{pathspec}---a @i{pathname designator}.

@i{truename}---a @i{physical pathname} or @b{nil}.

@subsubheading  Description::  

@b{probe-file} tests whether a file exists.

@b{probe-file} returns @i{false} if there is no file named @i{pathspec},
and otherwise returns the @i{truename} of @i{pathspec}.

If the @i{pathspec} @i{designator} is an open @i{stream},
then @b{probe-file} produces the @i{truename} of its associated @i{file}.

If @i{pathspec} is a @i{stream}, whether open or closed,
it is coerced to a @i{pathname} as if by the @i{function} @b{pathname}.

@subsubheading  Affected By::

The host computer's file system.

@subsubheading  Exceptional Situations::

An error of @i{type} @b{file-error} is signaled if @i{pathspec} is @i{wild}.

An error of @i{type} @b{file-error} is signaled
if the @i{file system} cannot perform the requested operation.

@subsubheading  See Also::

@ref{truename}
,
@ref{open}
,
@ref{ensure-directories-exist}
,
@b{pathname},

@b{logical-pathname},

@ref{File System Concepts},
@ref{File Operations on Open and Closed Streams},

@ref{Pathnames as Filenames}

@node ensure-directories-exist, truename, probe-file, Files Dictionary
@subsection ensure-directories-exist                                         [Function]

@code{ensure-directories-exist}  @i{pathspec {&key} verbose} @result{}  @i{pathspec, created}

@subsubheading  Arguments and Values::

@i{pathspec}---a @i{pathname designator}.

@i{verbose}---a @i{generalized boolean}.

@i{created}---a @i{generalized boolean}.

@subsubheading  Description::  

Tests whether the directories containing the specified @i{file} actually exist,
and attempts to create them if they do not.

If the containing directories do not exist and if @i{verbose} is @i{true}, 
then the @i{implementation} is permitted (but not required) 
to perform output to @i{standard output} saying what directories were created.
If the containing directories exist, or if @i{verbose} is @i{false},
this function performs no output.

The @i{primary value} is the given @i{pathspec} so that this operation can
be straightforwardly composed with other file manipulation expressions.
The @i{secondary value}, @i{created}, is @i{true} if any directories were
created.

@subsubheading  Affected By::

The host computer's file system.

@subsubheading  Exceptional Situations::

An error of @i{type} @b{file-error} is signaled if the host, device, or directory
part of @i{pathspec} is @i{wild}.

If the directory creation attempt is not successful,
an error of @i{type} @b{file-error} is signaled;
if this occurs, 
it might be the case that none, some, or all
of the requested creations have actually occurred 
within the @i{file system}.

@subsubheading  See Also::

@ref{probe-file}
,
@ref{open}
,

@ref{Pathnames as Filenames}

@node truename, file-author, ensure-directories-exist, Files Dictionary
@subsection truename                                                         [Function]

@code{truename}  @i{filespec} @result{}  @i{truename}

@subsubheading  Arguments and Values:: 

@i{filespec}---a @i{pathname designator}.

@i{truename}---a @i{physical pathname}.

@subsubheading  Description::

@b{truename} tries to find the @i{file} indicated by 
@i{filespec} and returns its @i{truename}.
If the @i{filespec} @i{designator} is an open @i{stream},
its associated @i{file} is used.

If @i{filespec} is a @i{stream},
@b{truename} can be used whether the @i{stream}
is open or closed. It is permissible for @b{truename} 
to return more specific information after the @i{stream}
is closed than when the @i{stream} was open.

If @i{filespec} is a @i{pathname} 
it represents the name used to open the file. This may be, but is
not required to be, the actual name of the file. 

@subsubheading  Examples::

@example
;; An example involving version numbers.  Note that the precise nature of
;; the truename is implementation-dependent while the file is still open.
 (with-open-file (stream ">vistor>test.text.newest")
   (values (pathname stream)
           (truename stream)))
@result{}  #P"S:>vistor>test.text.newest", #P"S:>vistor>test.text.1"
@i{OR}@result{} #P"S:>vistor>test.text.newest", #P"S:>vistor>test.text.newest"
@i{OR}@result{} #P"S:>vistor>test.text.newest", #P"S:>vistor>_temp_._temp_.1"

;; In this case, the file is closed when the truename is tried, so the
;; truename information is reliable.
 (with-open-file (stream ">vistor>test.text.newest")
   (close stream)
   (values (pathname stream)
           (truename stream)))
@result{}  #P"S:>vistor>test.text.newest", #P"S:>vistor>test.text.1"

;; An example involving TOP-20's implementation-dependent concept 
;; of logical devices -- in this case, "DOC:" is shorthand for
;; "PS:<DOCUMENTATION>" ...
 (with-open-file (stream "CMUC::DOC:DUMPER.HLP")
   (values (pathname stream)
           (truename stream)))
@result{}  #P"CMUC::DOC:DUMPER.HLP", #P"CMUC::PS:<DOCUMENTATION>DUMPER.HLP.13"
@end example

@subsubheading  Exceptional Situations::

An error of @i{type} @b{file-error} is signaled if an appropriate @i{file}
cannot be located within the @i{file system} for the given @i{filespec},

or if the @i{file system} cannot perform the requested operation.

An error of @i{type} @b{file-error} is signaled if @i{pathname} is @i{wild}.

@subsubheading  See Also::

@b{pathname},
@b{logical-pathname},
@ref{File System Concepts},

@ref{Pathnames as Filenames}

@subsubheading  Notes::

@b{truename} may be used to account for any @i{filename} translations 
performed by the @i{file system}.

@node file-author, file-write-date, truename, Files Dictionary
@subsection file-author                                                      [Function]

@code{file-author}  @i{pathspec} @result{}  @i{author}

@subsubheading  Arguments and Values::

@i{pathspec}---a @i{pathname designator}.

@i{author}---a @i{string} or @b{nil}.

@subsubheading  Description::

Returns a @i{string} naming the author of the @i{file} specified by @i{pathspec},
or @b{nil} if the author's name cannot be determined.

@subsubheading  Examples::

@example
 (with-open-file (stream ">relativity>general.text")
   (file-author s))
@result{}  "albert"
@end example

@subsubheading  Affected By::
The host computer's file system.

Other users of the @i{file} named by @i{pathspec}.
@subsubheading  Exceptional Situations::

An error of @i{type} @b{file-error} is signaled if @i{pathspec} is @i{wild}.

An error of @i{type} @b{file-error} is signaled
if the @i{file system} cannot perform the requested operation.

@subsubheading  See Also::

@b{pathname},
@b{logical-pathname},
@ref{File System Concepts},

@ref{Pathnames as Filenames}

@node file-write-date, rename-file, file-author, Files Dictionary
@subsection file-write-date                                                  [Function]

@code{file-write-date}  @i{pathspec} @result{}  @i{date}

@subsubheading  Arguments and Values::

@i{pathspec}---a @i{pathname designator}.

@i{date}---a @i{universal time} or @b{nil}.

@subsubheading  Description::

Returns a @i{universal time} representing the time at which the @i{file} 
specified by @i{pathspec} was last written (or created), 
or returns @b{nil} if such a time cannot be determined.

@subsubheading  Examples::

@example
 (with-open-file (s "noel.text" 
                    :direction :output :if-exists :error)
   (format s "~&Dear Santa,~2
                Please leave lots of toys.~2
             ~2
   (truename s))
@result{}  #P"CUPID:/susan/noel.text"
 (with-open-file (s "noel.text")
   (file-write-date s))
@result{}  2902600800
@end example

@subsubheading  Affected By::

The host computer's file system.

@subsubheading  Exceptional Situations::

An error of @i{type} @b{file-error} is signaled if @i{pathspec} is @i{wild}.

An error of @i{type} @b{file-error} is signaled
if the @i{file system} cannot perform the requested operation.

@subsubheading  See Also::

@ref{Universal Time},

@ref{Pathnames as Filenames}

@node rename-file, delete-file, file-write-date, Files Dictionary
@subsection rename-file                                                      [Function]

@code{rename-file}  @i{filespec new-name} @result{}  @i{defaulted-new-name, old-truename, new-truename}

@subsubheading  Arguments and Values::

@i{filespec}---a @i{pathname designator}.

@i{new-name}---a @i{pathname designator} 
other than a @i{stream}.

@i{defaulted-new-name}---a @i{pathname}

@i{old-truename}---a @i{physical pathname}.

@i{new-truename}---a @i{physical pathname}.

@subsubheading  Description::

@b{rename-file} modifies the file system in such a way
that the file indicated by @i{filespec} is renamed to
@i{defaulted-new-name}.

It is an error to specify a filename containing a @i{wild} component,
for @i{filespec} to contain a @b{nil} component where the file system does
not permit a @b{nil} component, or for the result of defaulting missing
components of @i{new-name} from @i{filespec} to contain a @b{nil} component
where the file system does not permit a @b{nil} component.

If @i{new-name} is a @i{logical pathname}, 
@b{rename-file} returns a @i{logical pathname} as its @i{primary value}.

@b{rename-file} 
returns three values if successful.  The @i{primary value}, @i{defaulted-new-name},
is the resulting name which is composed of
@i{new-name} with any missing components filled in by performing
a @b{merge-pathnames} operation using @i{filespec} as the defaults.
The @i{secondary value}, @i{old-truename},
is the @i{truename} of the @i{file} before it was renamed.
The @i{tertiary value}, @i{new-truename},
is the @i{truename} of the @i{file} after it was renamed.

If the @i{filespec} @i{designator} is an open @i{stream},
then the @i{stream} itself and the file associated with it are 
affected (if the @i{file system} permits).

@subsubheading  Examples::

@example
;; An example involving logical pathnames.
 (with-open-file (stream "sys:chemistry;lead.text"
                         :direction :output :if-exists :error)
   (princ "eureka" stream)
   (values (pathname stream) (truename stream)))
@result{}  #P"SYS:CHEMISTRY;LEAD.TEXT.NEWEST", #P"Q:>sys>chem>lead.text.1"
 (rename-file "sys:chemistry;lead.text" "gold.text")
@result{}  #P"SYS:CHEMISTRY;GOLD.TEXT.NEWEST",
   #P"Q:>sys>chem>lead.text.1",
   #P"Q:>sys>chem>gold.text.1"
@end example

@subsubheading  Exceptional Situations::

If the renaming operation is not successful, an error of @i{type} @b{file-error} is signaled.

An error of @i{type} @b{file-error} might be signaled if @i{filespec} is @i{wild}.

@subsubheading  See Also::

@ref{truename}
,
@b{pathname},
@b{logical-pathname},
@ref{File System Concepts},

@ref{Pathnames as Filenames}

@node delete-file, file-error, rename-file, Files Dictionary
@subsection delete-file                                                      [Function]

@code{delete-file}  @i{filespec} @result{}  @i{@b{t}}

@subsubheading  Arguments and Values::

@i{filespec}---a @i{pathname designator}.

@subsubheading  Description::

Deletes the @i{file} specified by @i{filespec}.

If the @i{filespec} @i{designator} is an open @i{stream},
then @i{filespec} and the file associated with it are affected 
(if the file system permits),
in which case @i{filespec} might be closed immediately,
and the deletion might be immediate or delayed until @i{filespec} is explicitly closed,
depending on the requirements of the file system.

It is @i{implementation-dependent} whether an attempt
to delete a nonexistent file is considered to be successful.

@b{delete-file} returns @i{true} if it succeeds,
or signals an error of @i{type} @b{file-error} if it does not.

The consequences are undefined 
    if @i{filespec} has a @i{wild} component,
 or if @i{filespec} has a @b{nil} component 
     and the file system does not permit a @b{nil} component.

@subsubheading  Examples::

@example
 (with-open-file (s "delete-me.text" :direction :output :if-exists :error))
@result{}  NIL
 (setq p (probe-file "delete-me.text")) @result{}  #P"R:>fred>delete-me.text.1"
 (delete-file p) @result{}  T
 (probe-file "delete-me.text") @result{}  @i{false}
 (with-open-file (s "delete-me.text" :direction :output :if-exists :error)
   (delete-file s))
@result{}  T
 (probe-file "delete-me.text") @result{}  @i{false}
@end example

@subsubheading  Exceptional Situations::

If the deletion operation is not successful, an error of @i{type} @b{file-error} is signaled.

An error of @i{type} @b{file-error} might be signaled if @i{filespec} is @i{wild}.

@subsubheading  See Also::

@b{pathname},
@b{logical-pathname},
@ref{File System Concepts},

@ref{Pathnames as Filenames}

@node file-error, file-error-pathname, delete-file, Files Dictionary
@subsection file-error                                                 [Condition Type]

@subsubheading  Class Precedence List::
@b{file-error},
@b{error},
@b{serious-condition},
@b{condition},
@b{t}

@subsubheading  Description::

The @i{type} @b{file-error} consists of error conditions that occur during 
an attempt to open or close a file, or during some low-level transactions 
with a file system.  The ``offending pathname'' is initialized by 
the @t{:pathname} initialization argument to @b{make-condition}, and is @i{accessed}
by the @i{function} @b{file-error-pathname}.

@subsubheading  See Also::

{file-error-pathname},
@ref{open}
,
@ref{probe-file}
,
@ref{directory}
,
@ref{ensure-directories-exist}

@node file-error-pathname,  , file-error, Files Dictionary
@subsection file-error-pathname                                              [Function]

@code{file-error-pathname}  @i{condition} @result{}  @i{pathspec}

@subsubheading  Arguments and Values:: 

@i{condition}---a @i{condition} of @i{type} @b{file-error}.

@i{pathspec}---a @i{pathname designator}.

@subsubheading  Description::

Returns the ``offending pathname'' of a @i{condition} of @i{type} @b{file-error}.

@subsubheading  Exceptional Situations::

@subsubheading  See Also::

@b{file-error},
@ref{Conditions}

@c end of including dict-files

@c %**end of chapter

