The predicates described in this section provide ISO compliant I/O, where streams are explicitly created using the predicate open/3. The resulting stream identifier is then passed as a parameter to the reading and writing predicates to specify the source or destination of the data.
This schema is not vulnerable to filename and stream ambiguities as well as changes to the working directory. On the other hand, using the notion of current-I/O simplifies reusability of code without the need to pass arguments around. E.g., see with_output_to/2.
SWI-Prolog streams are, compatible with the ISO standard, either input or output streams. To accommodate portability to other systems, a pair of streams can be packed into a stream-pair. See stream_pair/3 for details.
SWI-Prolog stream handles are unique symbols that have no syntactical 
representation. They are written as <stream>(hex-number), 
which is not valid input for read/1. 
They are realised using a blob of type stream (see blob/2 
and section 12.4.9).
read, write, append or update. 
Mode
append opens the file for writing, positioning the file 
pointer at the end. Mode update opens the file for writing, 
positioning the file pointer at the beginning of the file without 
truncating the file. Stream is either a variable, in which 
case it is bound to an integer identifying the stream, or an atom, in 
which case this atom will be the stream identifier.97New 
code should use the alias(Alias) option for compatibility 
with the ISO standard.
SWI-Prolog also allows SrcDest to be a term pipe(Command). 
In this form, Command is started as a child process and if
Mode is write, output written to Stream 
is sent to the standard input of Command. Vice versa, if Mode 
is
read, data written by Command to the standard 
output can be read from Stream. On Unix systems, Command 
is handed to popen() which hands it to the Unix shell. On Windows, Command 
is executed directly and therefore shell syntax such as redirecting 
(using e.g., > file) does not work. Use of 
the
pipe(Command) feature is deprecated. The predicate
process_create/3 
from library(process) provides a richer and more portable 
alternative for interacting with processes including handling all three 
standard streams.
If SrcDest is an IRI, i.e., starts with
<scheme>://, where <scheme> 
is a non-empty sequence of lowercase ASCII letters open/3,4 
calls hooks registered by register_iri_scheme/3. 
Currently the only predefined IRI scheme is res, providing 
access to the resource database. See
section 14.4.
The following Options are recognised by open/4:
?- open(data, read, Fd, [alias(input)]).
        ...,
        read(input, Term),
        ...
true for mode read and
false for mode write. See also stream_property/2 
and especially section 
2.19.1.1 for a discussion of this feature.full (default) defines 
full buffering, line buffering by line, and false 
implies the stream is fully unbuffered. Smaller buffering is useful if 
another process or the user is waiting for the output as it is being 
produced. See also flush_output/[0,1]. 
This option is not an ISO option.true (default), the stream is closed on an abort (see
abort/0). 
If false, the stream is not closed. If it is an output 
stream, however, it will be flushed. Useful for logfiles and if the 
stream is associated to a process (using the pipe/1 
construct).write,
append or update mode. Currently, List 
is a list of atoms that describe the permissions of the created file.98Added 
after feedback from Joachim Shimpf and Per Mildner. Defined 
values are below. Not recognised values are silently ignored, allowing 
for adding platform specific extensions to this set.
Note that if List is empty, the created file has no 
associated access permissions. The create options map to the POSIX mode 
option of open(), where read map to 0444, write 
to 0222 and execute to 0111. On POSIX systems, the final 
permission is defined as (mode & umask).~
text is derived from the 
Prolog flag encoding. 
For binary streams the default encoding is octet. 
For details on encoding issues, see section 
2.19.1.eof_code, which makes get0/1 
and friends return -1, and read/1 
and friends return the atom
end_of_file. Repetitive reading keeps yielding the same 
result. Action error is like eof_code, but 
repetitive reading will raise an error. With action reset, 
Prolog will examine the file again and return more data if the file has 
grown.none, 
which does not lock the file. The value read or shared 
means other processes may read the file, but not write it. The value
write or exclusive means no other process may 
read or write the file.
Locks are acquired through the POSIX function fcntl() using the 
command
F_SETLKW, which makes a blocked call wait for the lock to 
be released. Please note that fcntl() locks are advisory and 
therefore only other applications using the same advisory locks honour 
your lock. As there are many issues around locking in Unix, especially 
related to NFS (network file system), please study the fcntl() manual 
page before trusting your locks!
The lock option is a SWI-Prolog extension.
posix, dos or detect. This option 
is ignored for binary streams. Using detect on an output 
stream raises an exception. See also set_stream/2.text (default), Prolog will write a text file in 
an operating system compatible way. Using type binary the 
bytes will be read or written without any translation. See also the 
option encoding.lock option. If
false (default true), the open call returns 
immediately with an exception if the file is locked. The exception has 
the format
permission_error(lock, source_sink, SrcDest).
The option reposition is not supported in SWI-Prolog. 
All streams connected to a file may be repositioned.
/dev/null) or exploit the counting properties. The 
initial encoding of Stream is utf8, enabling 
arbitrary Unicode output. The encoding can be changed to determine byte 
counts of the output in a particular encoding or validate if output is 
possible in a particular encoding. For example, the code below 
determines the number of characters emitted when writing Term.
write_length(Term, Len) :-
        open_null_stream(Out),
        write(Out, Term),
        character_count(Out, Len0),
        close(Out),
        Len = Len0.
If the closed stream is the current input, output or error stream, the stream alias is bound to the initial standard I/O streams of the process. Calling close/1 on the initial standard I/O streams of the process is a no-op for an input stream and flushes an output stream without closing it.99This behaviour was defined with purely interactive usage of Prolog in mind. Applications should not count on this behaviour. Future versions may allow for closing the initial standard I/O streams.
close(Stream, [force(true)]) as the only option. 
Called this way, any resource errors (such as write errors while 
flushing the output buffer) are ignored.full, line or false. 
See also open/4.true, a BOM (Byte Order Mark) was 
detected while opening the file for reading, or a BOM was written while 
opening the stream. See section 
2.19.1.1 for details.F_SETFD using the flag
FD_CLOEXEC on Unix and (negated) HANDLE_FLAG_INHERIT 
on Windows.not, at or past. See 
also
at_end_of_stream/[0,1].eof_code, reset 
or
error. See open/4 
for details.true, the stream is in an error state. Applies to both 
input and output streams.SWI-Stream.h.read.read, write, append 
and the SWI-Prolog extension update.posix or dos. If dos, text 
streams will emit \r\n for \n and discard \r 
from input streams. Default depends on the operating system.st_nlink.write, append 
or
update.error (throw 
an I/O error exception), prolog (write \x<hex>\),
unicode (write \uXXXX or \UXXXXXXXX 
escape sequences) or xml (write &#...; XML 
character entity). The initial mode is unicode for the user 
streams and
error for all other streams. See also section 
2.19.1 and
set_stream/2.infinite.text or binary.true 
if the stream is associated with a terminal. See also set_stream/2.error (default) or ignore. 
The latter is intended to deal with service processes for which the 
standard output handles are not connected to valid streams. In these 
cases write errors may be ignored on user_error.[] 
if the stream refers to some other object.
Mode is one of read or write.
This predicate is deprecated. New code should use the ISO predicate stream_property/2.
Stream-pairs can be used by all I/O operations on streams, where the operation selects the appropriate member of the pair. The predicate close/1 closes the still open streams of the pair.100As of version 7.1.19, it is allowed to close one of the members of the stream directly and close the pair later. The output stream is closed before the input stream. If closing the output stream results in an error, the input stream is still closed. Success is only returned if both streams were closed successfully.
position(Pos) property. See also seek/4.position(Pos) property.
Field is one of line_count, line_position,
char_count or byte_count. See also line_count/2,
line_position/2, character_count/2 
and byte_count/2.101Introduced 
in version 5.6.4 after extending the position term with a byte count. 
Compatible with SICStus Prolog.bof, current or eof, 
indicating positioning relative to the start, current point or end of 
the underlying object. NewLocation is unified with the new 
offset, relative to the start of the stream.
Positions are counted in‘units'. A unit is 1 byte, except for text files using 2-byte Unicode encoding (2 bytes) or wchar encoding (sizeof(wchar_t)). The latter guarantees comfortable interaction with wide-character text objects. Otherwise, the use of seek/4 on non-binary files (see open/4) is of limited use, especially when using multi-byte text encodings (e.g. UTF-8) or multi-byte newline files (e.g. DOS/Windows). On text files, SWI-Prolog offers reliable backup to an old position using stream_property/2 and set_stream_position/2. Skipping N character codes is achieved calling get_code/2 N times or using copy_stream_data/3, directing the output to a null stream (see open_null_stream/1). If the seek modifies the current location, the line number and character position in the line are set to 0.
If the stream cannot be repositioned, a permission_error 
is raised. If applying the offset would result in a file position less 
than zero, a domain_error is raised. Behaviour when seeking 
to positions beyond the size of the underlying object depend on the 
object and possibly the operating system. The predicate seek/4 
is compatible with Quintus Prolog, though the error conditions and 
signalling is ISO compliant. See also stream_property/2 
and set_stream_position/2.
eof_action only applies to the read stream,
representation_errors only applies to the write 
stream and trying to set alias or line_position 
on a pair results in a permission_error exception. See also
stream_property/2 
and open/4.
set_stream(S, 
current_input) is the same as set_input/1, 
and by setting the alias of a stream to user_input, etc., 
all user terminal input is read from this stream. See also interactor/0.full, line 
or false.close_on_exec property. See stream_property/2.bom causes the stream to check whether the current 
character is a Unicode BOM marker. If a BOM marker is found, the 
encoding is set accordingly and the call succeeds. Otherwise the call 
fails.eof_code, reset 
or
error.position).detect. It will be set to dos if a \r 
character was removed.
error(timeout_error(read, Stream), _)
text or binary. 
See also open/4 
and the encoding property of streams. Switching to binary 
sets the encoding to octet. Switching to
text sets the encoding to the default text encoding.set_stream(S, record_position(true)) resets the 
position the start of line 1.user_input and
current_input of the calling thread. Out becomes
user_output and current_output. If Error 
equals
Out an unbuffered stream is associated to the same 
destination and linked to user_error. Otherwise Error 
is used for
user_error. Output buffering for Out is set to
line and buffering on Error is disabled. See 
also prolog/0 
and set_stream/2. 
The clib package provides the library library(prolog_server), 
creating a TCP/IP server for creating an interactive session to Prolog.stdin. Out 
becomes
stdout. If Error equals Out an 
unbuffered stream is associated to the same destination and linked to stderr. 
Otherwise Error is used for stderr. Output 
buffering for
Out is set to line and buffering on Error is 
disabled. The operating system I/O streams are shared across all 
threads. The three streams must be related to a file descriptor 
or a
domain_error file_stream is raised. See also
stream_property/2, 
property file_no(Fd).
Where set_prolog_IO/3 
rebinds the Prolog streams user_input,
user_output and user_error for a specific 
thread providing a private interactive session, set_system_IO/3 
rebinds the shared console I/O and also captures Prolog kernel events 
(e.g., low-level debug messages, unexpected events) as well as messages 
from foreign libraries that are directly written to stdout 
or
stderr.
This predicate is intended to capture all output in situations where standard I/O is normally lost, such as when Prolog is running as a service on Windows.