• Aucun résultat trouvé

Accessing Files

Dans le document Introduction to the 1/0 System (Page 138-169)

5. File and Directory Access

5.1 Accessing Files

Genera lets you 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 Symbolics computer itself, if the machine has its own file system. This section tells you how to get a stream that reads or writes a given file, and what the device-dependent operations on that stream are. Files are named with

pathnames. Since pathnames are quite complex they have their own chapter. See the section "Naming of Files", page 51.

The options used when opening a file are normally alternating keywords and values, like any other function that takes keyword arguments. The file-opening options control whether the stream is for input from a existing file or output to a new file, whether the file is text or binary, and so on.

The following option keywords are recognized. Unless otherwise noted, they are supported generically. Additional keywords can be implemented by particular file system hosts.

:byte-size

: characters

The possible values are nil (the default), a number in the range 1 to 16 inclusive, which is the number of bits per byte, and : 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, nil 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, nil selects the default byte size of 16 bits. The preferred way to specify the byte-size for files is to use the :element-type keyword.

This option specifies whether the objects contained in the file are characters or flXnums. The preferred way to specify character files is to use the :element-type keyword.

Value t

nil : default

Meaning

Specifies that the file contains character objects. This is the default.

Specifies that the file is a binary file.

On output, :default is always t, as character files are created by default. On input,

:deleted

:direct :direction

:default specifies that the file system

determine from the file properties for LMFS section "Direct Access File Streams", page 13.

The :direction option allows the following values:

: input and output. Bidirectionality is supported only if the stream is to be a direct stream, that is, :direct t is given as well. See the section

"Direct Access File Streams", page 13.

A "probe" opening; no data are to be about the existence of its directory component.

: element-type

nil

Otherwise, the semantics are the same as :probe. If the directory is not found, a file lookup error is signalled.

This is the same as probe. No data are transferred, and the file is being opened only to gain access to or change its properties. If the value of :direction is nil and the value of :error is nil, then open will return the error object instead of nil. If the value of

:if-does-not-exist is nil, the error object will still be returned.

This argument specifies the type of Lisp object transferred by the stream. Anything that can be recognized as being a finite subtype of character or integer is acceptable. In particular, the following types are recognized:

string-char

character

The object being transferred is a string-character. The functions read-char and/or write-char can be used on the stream. This is the default.

The object being transferred is any character, not just a string-character. The functions read-char and/or write-char can be used on the stream.

(unsigned-byte n)The object being transferred is an unsigned byte (a non-negative integer) of size n. The functions read-byte and/or write-byte can be used on the stream.

unsigned-byte The object being transferred is an unsigned byte (a non-negative integer) whose size is determined by the file system. The functions read-byte and/or write-byte can be used on the stream.

(signed-byte n) The object being transferred is a signed byte of size n. The functions read-byte and/or write-byte can be used on the stream.

signed-byte The object being transferred is a signed byte whose size is determined by the file system.

The functions read-byte and/or write-byte can be used on the stream.

: error

fs:file-operation-failure condition is signalled. t is the recommended value for this option. The others have been provided for compatibility with previous systems to aid in converting programs. See the section "File-System Errors" in Symbolics Common Lisp: Language Concepts.

The option has three possible values: remember that the :pathname message sent to the stream finds out what file name was really opened. The alternative to :reprompt is to use :error t and set up a condition handler for fs:file-operation-failure that explains the condition and prompts the user.

:estimated-Iength The value of the :estimated-Iength option can be nil (the

default), which means there is no estimated length, or a number of bytes indicating the estimated length of a file to be written.

Some file systems use this to optimize disk allocation.

:if-does-not-exist Specifies the action to be taken if the file does not already exist. filename is either :newest or :unspecific.

File systems without version numbers can

:rename-and-delete on those systems that distinguish deletion from expunging). Then creates a new file with the specified name. On most file

systems, this renaming happens at the time of a successful close.

The existing file is used, and output

operations on the stream destructively modify the file. The file pointer is initially positioned at the beginning of the file; however, the file is not truncated back to length zero when it is opened.

The existing file is used, and output

operations on the stream destructively modify the file. The file pointer is initially positioned

"abort" mode. This differs from :new-version in that :supersede creates a new file with the same name as the old one, rather than a file name with a higher version number.

Does not create a file or even a stream.

Instead, simply returns nil to indicate failure.

This is overridden when the value of :direction is either nil or :probe and the value of :error is nil. In this case, the error object is returned instead of nil.

:preserve-dates The default is nil. If t is specified, the file's reference and modification dates are not updated.

:raw : submit

The value can be nil (the default) or t, which disables all character set translation in ASCII files.

This is an option to open used to get batch jobs. Currently, this is implemented only for V AXNMS. When the file you are writing is closed, the file is submitted as a batch job by using this option.

: super-image The value can be nil (the default), or t which disables the special treatment of Rubout in ASCII files. Normally Rubout is an escape that causes the following character to be interpreted specially, allowing all characters from 0 through 376 to be stored. This applies to PDP-10 file servers only.

:temporary The default is nil. If t is specified, the file is marked as temporary, if the file system has that concept.

with-open-file (stream-variable filename . options ... ) &body body... Special Form Evaluates the body forms with the variable stream-variable bound to a stream that reads or writes the file named by the value of filename. The options forms evaluate to the file-opening options to be used.

When control leaves the body, either normally or abnormally (via throw), the file is closed. If a new output file is being written, and control leaves abnormally, the fi~e is aborted and it is as if it were never written.

Because it always closes the file, even when an error exit is taken,

with-open-file is preferred over open. Opening a large number of files and forgetting to close them tends to break some remote file servers, ITS's for example.

filename is the name of the file to be opened; it can be a pathname object, a string, or a symbol. It can be anything acceptable to fs:parse-pathname.

See the section "Naming of Files", page 51. The complete rules for parsing pathnames are explained there.

If an error occurs, such as file not found, the user is asked to supply an alternate pathname, unless this is overridden by options. At that point, the user can quit out or enter the Debugger, if the error was not due to a misspelled pathname.

If you are opening the file to read it with read, and you want to bind the package and so forth, see the special functions for handling file attributes.

See the function fs:read-attribute-list, page 158. See the function fs:file-attribute-bindings, page 159.

with-open-file-case (var pathname . options) &body clauses Special Form Opens a file, binding the input stream to var, using the pathname and options given in the arguments. In the following example, it executes the

first clause when the file is not found. When the file is found without error, it executes the second clause, which is the real reason for trying to open the file in the first place.

(with-open-file-case (x "f:>dla>foo.lisp" ':direction ':input) (fs:file-not-found (send x ':report error-output»

(:no-error (stream-copy-until-eof x standard-output»)

Any errors other than file-not-found (for example, access violations or an unresponsive host) cause an error to be signalled normally.

with-open-file-case-if cond (var pathname . options) &body clauses Special Form Opens a file, binding the input stream to var, using pathname and options given in the arguments. All clauses are evaluated, but the error handling for the body is performed only if the predicate specified by cond returns t.

Any errors other than file-not-found (for example, access violations or an unresponsive host) cause an error to be signalled normally.

with-open-stream (stream-variable construction-form) &body body Special Form Like with-open-file except that you specify a form whose value is the stream, rather than arguments to open. This is used with nonfile streams.

See the special form with-open-file, page 135.

with-open-stream-case (var construction-form) &body clauses Special Form Opens a stream and binds it to var, using construction-form to create it. It then executes whichever clause is appropriate, given the condition that resulted from the attempt to create the stream. Refer to the example shown for with-open-file-case.

with-open-stream-case-if cond (var construction-form) &body clauses Special Form Opens a stream and binds it to var, using construction-form to create it.

All clauses are evaluated, but the error handling for the body is performed only if the predicate specified by cond returns t.

with-standard-io-environment &body body Special Form

All output in body is printed with *package*, *readtable*, and other

variables bound to consistent values. This is useful when you wish to write some data the you will use read to retrieve later. This is a custom

environment that you create, passing all variables and values that are important before body.

with-standard-io-environment inhibits the effect of #. while reading. This prevents other forms being read and used as trojan horses. This can be inhibited by rebinding si:*suppress-read-eval to nil.

with-input-from-string (stream string &key index (start 0) end) Special Form

&body body

body is executed as an explicit progn with the variable stream bound to a character input stream that supplies successive characters from the value of the form string. with-input-from-string returns the results from the last form of the body.

The input stream is automatically closed on exit from the

with-input-from-string form, no matter whether the exit is normal or abnormal. The stream should be regarded as having dynamic extent. The following keywords can be used:

keyword :index

:start :end

Examples:

value

The form after the :index keyword should be a place acceptable to setf. If the form is exited normally, then the place will have stored into it the index into string indicating the first character not read, or the length of the string if all characters were used. The place is not updated as reading progresses, but only at the end of the operation.

An argument indicating the beginning of a substring of string to be used. :start defaults to O.

An argument indicating the end of a substring of string to be used. :end defaults to the length of the string.

(values (with-input-from-string

(stream "A long boring string" :index i) (read stream)) i) => A and 2

(values (with-input-from-string

(stream "A long boring string" :index :start 2) (read stream)) i) => LONG and 7

(values (with-input-from-string

(stream "A long boring string" :index :start 9 :end 12) (read stream)) i) => RIN and 12

zl:with-input-from-string (var string &optional index limit) &body body

Special Form

The form:

(with-input-from-string (var string) body)

evaluates the forms in body with the variable var bound to a stream that reads characters from the string which is the value of the form string.

The value of the special form is the value of the last form in its body.

The stream is a function that only works inside the with-input-from-string special form, so be careful what you do with it. You cannot use it after control leaves the body, and you cannot nest two with-input-from-string special forms and use both streams since the special-variable bindings associated with the streams conflict. It is done this way to avoid any allocation of memory.

After string you can optionally specify two additional "arguments". The first is index:

(wi th-i nput-from-stri ng (var string index) body)

uses index as the starting index into the string, and sets index to the index of the first character not read when with-input-from-string returns. If the whole string is read, it is set to the length of the string. Since index is updated it cannot be a general expression; it must be a variable or a setfable reference. The index is not updated in the event of an abnormal exit from the body, such as a throw. The value of index is not updated until with-input-from-string returns, so you cannot use its value within the body to see how far the reading has proceeded.

Use of the index feature prevents multiple values from being returned out of the body, currently.

(wi th-i nput-from-stri ng (var string index limit) body)

uses the value of the form limit, if the value is not nil, in place of the length of the string. If you want to specify a limit but not an index, write nil for index. Examples:

(setq i 0) => 0

(values (zl :with-input-from-string

(stream "A long boring string" i) (read stream)) i) => A and 2 (values (zl :with-input-from-string

(stream "A long boring string" i) (read stream)) i) => LONG and 7

(values (21 :with-input-from-string

(stream "A long boring string" i 12) (read stream» i) => BORIN and 12

with-output-to-string (stream &optional string &key index) &body Special Form body

body is executed as an explicit progn with the variable stream bound to a character output stream that saves characters in string. If string is not specified, with-output-to-string returns the results from the last form of the body as a string.

If string is specified, it must be a string with a fill pointer. The output is incrementally appended to the string, as if using vector-push-extend if the string is adjustable, and as if using vector-push otherwise. In this case, with-output-to-string returns the results from the last form of the body.

The output stream is automatically closed on exit from the

with-output-to-string form, no matter whether the exit is normal or abnormal. The stream should be regarded as having dynamic extent.

The form after the :index keyword should be a place acceptable to setf. If the form is exited normally, then the place will have stored into it the index into string indicating the first character not read, or the length of the string if all characters were used. The place is not updated as reading progresses, but only at the end of the operation.

Examples:

(setq string (make-array 2 :element-type 'string-char :fill-pointer t» => ..

(val ues (wi th-output-to-stri ng (stream ni 1 : index i)

(write-string "a happy day" stream :start 2 :end 7»

string i) => "happy" and .. and 17

(values (with-output-to-string (stream string :index i) (write-string "a happy day" stream :start 2 :end 7»

stri ng i) => "a happy day" and .. and 22

zl:with-output-to-string (var &optional (string nil string-p) index) Special Form

&body body

This special form provides a variety of ways to send output to a string through an I/O stream.

(with-output-to-string (var) body)

evaluates the forms in body with var bound to a stream that saves the characters output to it in a string. The value of the special form is the string.

(wi th-output-to-stri ng (var string) body)

appends its output to the string that is the value of the form string. (This is like the string-nconc function). The value returned is the value of the last form in the body, rather than the string. Multiple values are not returned. string must have an array-leader; element 0 of the array-leader is used as the fill-pointer. If string is too small to contain all the output, zl:adjust-array-size is used to make it bigger.

If characters with font information are output, string must be of type sys:art-fat-string. See the section "sys:art-fat-string Array Type" in Symbolics Common Lisp: Language Concepts.

(wi th-output-to-stri ng (var string index) body)

is similar to the above except that index is a variable or setfable reference that contains the index of the next character to be stored into. It must be initialized outside the with-output-to-string and is updated upon normal exit. The value of index is not updated until with-output-to-string returns, so you cannot use its value within the body to see how far the writing has gotten. The presence of index means that string is not required to have a fill-pointer; if it does have one it is updated.

The stream is a "downward closure" simulated with special variables, so be careful what you do with it. You cannot use it after control leaves the body, and you cannot nest two with-output-to-string special forms and use both streams since the special-variable bindings associated with the streams conflict. It is done this way to avoid any allocation of memory. Examples:

(setq string (zl :make-array 2 :type Jzl :art-string :fill-pointer 2» => ., (setq i 0) => 0

(values (zl :with-output-to-string (stream nil i)

(write-string "a happy day" stream :start 2 :end 7»

string i) => "happy" and .. and 0

(values (zl :with-output-to-string (stream string i)

(write-string "a happy day" stream :start 2 :end 7»

string i) => "a happy day" and "han and 5

(values (zl :with-output-to-string (stream string i)

(write-string "a happy day" stream :start 2 :end 7)) string i) => "a happy day" and "han and 10

(values (zl:with-output-to-string (stream string)

(write-string "a happy day" stream :start 2 :end 7)) string i) => "a happy day" and "hahappy" and 10

sys:with-open-file-search (stream-variable Special Form

(operation defaults auto-retry) (type-list-function pathname • type-list-args) . open-options) body ...

Performs a with-open-file, searching for a file with one of the types in a list of file types. load uses this special form when not given a specific file type to search first for a binary file and then for a source file.

Performs a with-open-file, searching for a file with one of the types in a list of file types. load uses this special form when not given a specific file type to search first for a binary file and then for a source file.

Dans le document Introduction to the 1/0 System (Page 138-169)