The FS
interface provides persistent storage (files) and naming
(directories).
\index{directory}
INTERFACEFS ; IMPORT OSError, File, Pathname, Time; PROCEDURE GetAbsolutePathname(p: Pathname.T): Pathname.T RAISES {OSError.E};
Return an absolute pathname referring to the same file or
directory as p
.
The new pathname will not involve any symbolic links or relative arcs (that is, occurrences of
Pathname.Parent
or
Pathname.Current
.
\index{absolute pathname!from relative pathname}
The procedures OpenFile
and OpenFileReadonly
look up a pathname
and return a file handle, which is an object allowing a file to be
read and perhaps written. The returned value will be of some
subtype of File.T
, depending on the kind of object named by p
.
If the object is a regular file, the type will be RegularFile.T
.
If the object is a terminal, the type will be Terminal.T
. Other,
system-specific subtypes are also possible. Under appropriate
conditions, OpenFile
can create a new regular file. OSError.E
is raised if the pathname passed to OpenFile
or
OpenFileReadonly
is that of a directory.
TYPE CreateOption = {Never, Ok, Always}; AccessOption = {OnlyOwnerCanRead, ReadOnly, Default}; PROCEDURE OpenFile( p: Pathname.T; truncate: BOOLEAN := TRUE; create: CreateOption := CreateOption.Ok; template: File.T := NIL; access: AccessOption := AccessOption.Default): File.T RAISES {OSError.E};
Return an object permitting writing and reading an existing or
newly-created file named p
.
Suppose
p
names an existing regular file. If create = Always
,
then OSError.E
is raised. Otherwise, the existing file is
opened, after truncating it to zero size if truncate = TRUE
.
On the other hand, suppose the file named by p
does not exist.
If create = Never
, then OSError.E
is raised. Otherwise, a new
file is created. Normally the new file is a regular file, but some
implementations may determine the type of the new file from the
identity of the directory in which it is being created. The access
control settings of the new file are set using the values of
template
and access
. If template # NIL
, then access
is
ignored and the new file is given the same per-file access control
settings as template
. If template = NIL
, the file's access
control settings are determined by an implementation-defined
default value, with possible restrictions determined by the value
of access
:
\begin{description}
\item[OnlyOwnerCanRead
] read access is allowed only by this user
\item[ReadOnly
] write access is allowed to no one (except via the
File.T
returned by this call of OpenFile
)
\item[Default
] the default applies with no restrictions.
\end{description}
\index{creating a file}
\index{file!creation}
A newly-created file f
has
buffer(f) = stable(f) = empty sequence mtime(f) = current time locked(f) = Process.NullID
OpenFile
doesn't change mtime(f)
of an existing file f
.
If OpenFile
returns a regular file handle, say h
, then its
initial state will be:
type(h) = RegularFile.FileType readable(h) = writable(h) = TRUE cur(h) = 0 file(h) = file with pathname pTo append to an existing file, perform the call
EVAL h.seek(Origin.End, 0)after opening
h
.
PROCEDURE OpenFileReadonly(p: Pathname.T): File.T RAISES {OSError.E};
Return an object permitting reading the file named by p
.
If
p
names a regular file, the call OpenFileReadonly(p)
returns
a file handle h
with
type(h) = Atom.FromText("RegularFile") readable(h) = TRUE writable(h) = FALSE cur(h) = 0 file(h) = file with pathname p
PROCEDURE CreateDirectory(p: Pathname.T) RAISES {OSError.E};
Create a directory named by p
.
PROCEDURE DeleteDirectory(p: Pathname.T) RAISES {OSError.E};
Delete the directory named byp
.OSError.E
is raised if the directory contains entries (other than perhapsPathname.Current
andPathname.Parent
).
PROCEDURE DeleteFile(p: Pathname.T) RAISES {OSError.E};
Delete the file or device named byp
.OSError.E
is raised ifp
names a directory.
Note: Under Win32,
DeleteFile
raises OSError.E
if p
is open.
Under POSIX, an open file may be deleted; the file doesn't actually
disappear until every link (pathname) for it is deleted.
PROCEDURE Rename(p0, p1: Pathname.T) RAISES {OSError.E};
Rename the file or directory namedp0
asp1
.
Some implementations automatically delete an existing file named
p1
, others raise OSError.E
. Some implementations disallow a
rename where p0
and p1
name different physical storage devices
(different root directories or file systems).
TYPE Iterator <: PublicIterator; PublicIterator = OBJECT METHODS next(VAR (*OUT*) name: TEXT): BOOLEAN; nextWithStatus(VAR (*OUT*) name: TEXT; VAR (*OUT*) stat: File.Status): BOOLEAN RAISES {OSError.E}; close(); END; VAR (*CONST*) DirectoryFileType: File.Type;
Equal to {\tt Atom.FromText("Directory").}
PROCEDURE Iterate(p: Pathname.T): Iterator RAISES {OSError.E};
Return an iterator for the entries of the directory named by p
.
An
Iterator
supplies information about the entries in a
directory: names and, optionally, status. The iteration does not
include entries corresponding to Pathname.Current
or
Pathname.Parent
.
The methods have the following specifications:
If more entries remain, the call i.next(n)
sets n
to the name
of the next one and returns TRUE
. It returns FALSE
without
setting n
if no more entries remain.
If more entries remain, the call i.nextWithStatus(n, s)
sets n
to the name of the next one, sets s
to the status of that entry,
and returns TRUE
. The value of s.type
is DirectoryFileType
if the entry is a directory. The call returns FALSE
without
setting n
or s
if no more entries remain.
The call i.close()
releases the resources used by i
, after
which time it is a checked runtime error to use i
. Every
iterator should be closed.
You iterate over the entries in a directory with code like this:
VAR i := FS.Iterate(pathname); name: TEXT; BEGIN TRY WHILE i.next(name) DO Process name END FINALLY i.close() END ENDUse
nextWithStatus
instead of next
if you would otherwise call
Status
(or the File.T
status
method) on most of the entries
(in some implementations, nextWithStatus
requires an extra disk
access).
What can be assumed if a directory is being updated concurrently with an iteration? An entry that is not inserted or deleted will occur in the iteration at least once, and an entry that occurs in the iteration must have been in the directory at some moment.
PROCEDURE Status(p: Pathname.T): File.Status RAISES {OSError.E};
Return information about the file or directory named by p
.
Possible values of
stat.type
include
FS.DirectoryFileType (a directory) RegularFile.FileType (a disk file) Terminal.FileType (a terminal)If
p
is a disk file, stat.modificationTime
and stat.size
will
be set.
See also the status
method of File.T
and the nextWithStatus
method of Iterator
.
PROCEDURE SetModificationTime( p: Pathname.T; READONLY t: Time.T) RAISES {OSError.E};
Change the modification time of the file or directory named byp
tot
.
END FS.