ToDo: Create examples where necessary for this introduction.
This chapter deals with file access, that is opening files, passing files as arguments to procedures that work with them, and so on.
File access and manipulation in Scheme is done by means of ports (as the R5RS puts it: "To Scheme, an input port is a Scheme object that can deliver characters upon command, while an output port is a Scheme object that can accept characters"). When you want to work with a file it's necessary to first associate it with a port, you then feed this port to the procedures for I/O. It's required that ports associated with files be closed when they're no longer in use.
Ports can be opened for input or for output, but not for both (in PLT Scheme there exists the
open-input-output-file procedure, which returns 2 ports: one for input and one for output; more on this later). You can use the predicates
port?,
input-port?,
output-port? to know when a value is a port, and whether it's for input or output, respectively.
All I/O procedures take as an optional parameter a port, and if not specified they will use whatever value the procedures
current-input-port and
current-output-port return. This procedures are handled in PLT Scheme as parameter procedures, which means they can also be used to change the values for the default input/output ports (for more information see ...). PLT Scheme also provides a default error output port that can be obtained/modified using the parameter procedure
current-error-port.
Files are not the only objects you can associate with ports. You can also read from and write to string ports, pipes, and even custom ports.
-- Insert your favorite example code snippet for the above here --
Ports associated with files are of a special kind: they are file-stream ports. These differ from others in that they use a buffer, input file-stream ports cache characters in the buffer to speed up future reads, while output file-stream ports use the buffer to accumulate characters and write them as a group. This is one of the main reasons it can be confusing to have both input and output file-stream ports open on the same file at the same time, as their respective buffers are not necessarily syncrhronized.
To identify file-stream ports you can use the predicate
file-stream-port?. Buffered data in file-stream output ports can be forced out using
flush-output, although this is typically done automatically after each newline (this behavior can be changed using
file-stream-buffer-mode to, for instance, not wait for newlines but flush immediately).
Random file access can be achieved by using the procedure
file-position (not all file-stream ports support this, which if used in such a situation would raise a
exn:i/o:port exception). This can be used either to obtain the current read/write position of a port, and to change it. When specifying a position past the size of the file, it is first padded with
#\nul characters until the required size is met, and then the position is set. You should also know that changing the position on a file-access port causes it's buffer to be emptied first: for output ports it's flushed, and for input ports it's cleared.
ToDo: Insert
See Also s
--
FranciscoEscalona - 12 May 2004