SWI-Prolog provides two different packages for input and output. The native I/O system is based on the ISO standard predicates open/3, close/1 and friends.37Actually based on Quintus Prolog, providing this interface before the ISO standard existed. Being more widely portable and equipped with a clearer and more robust specification, new code is encouraged to use these predicates for manipulation of I/O streams.
Section 4.16.2 describes tell/1, see/1 and friends, providing I/O in the spirit of the outdated Edinburgh standard. These predicates are layered on top of the ISO predicates. Both packages are fully integrated; the user may switch freely between them.
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. New code is advised to use these predicates to manage input and output streams.
pipe(Command)', 
like see/1 
and tell/1. Mode 
is one of 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.38New code 
should use the alias(Alias) option for compatibility with 
the ISO standard The Options list can contain 
the following options:
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.
?- open(data, read, Fd, [alias(input)]).
        ...,
        read(input, Term),
        ...
text is derived from the 
Prolog flag encoding. 
For binary streams the default encoding is octet. 
For details on encoding issues, see section 
2.17.1.true for mode read and
false for mode write. See also stream_property/2 
and especially section 2.17.1.1 
for a discussion on this feature.eof_code 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.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, it will be flushed however. Useful for logfiles and if the 
stream is associated to a process (using the pipe/1 construct).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.
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 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 or output stream, the terminal is made the current input or output.
close(Stream, [force(true)]) as the only option. 
Called this way, any resource error (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.17.1.1 for details.not, at or past. See 
also
at_end_of_stream/[0,1].eof_code, reset 
or
error. See open/4 
for details.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.write, append 
or
update.error (throw 
and I/O error exception), prolog (write \...\ 
escape code or xml (write &#...; XML 
character entity). The initial mode is prolog for the user 
streams and
error for all other streams. See also section 
2.17.1 and set_stream/2.infinite.text or binary.true 
if the stream is associated with a terminal. See also set_stream/2.
[] if 
the stream refers to some other object.
Mode is one of read or write.position(Pos) property. See also seek/4.position(Position) 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.39Introduced 
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 
then 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.
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.eof_code, reset 
or
error.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.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.
The package for implicit input and output destination is (almost) compatible with Edinburgh DEC-10 and C-Prolog. The reading and writing predicates refer to resp. the current input- and output stream. Initially these streams are connected to the terminal. The current output stream is changed using tell/1 or append/1. The current input stream is changed using see/1. The streams current value can be obtained using telling/1 for output- and seeing/1 for input streams.
Source and destination are either a file, user, or a 
term `pipe(Command)'. The reserved stream name user 
refers to the terminal.40The ISO 
I/O layer uses user_input, user_output and user_error. 
In the predicate descriptions below we will call the source/destination 
argument `SrcDest'. Below are some examples of 
source/destination specifications.
| ?- see(data). | % Start reading from file `data'. | 
| ?- tell(user). | % Start writing to the terminal. | 
| ?- tell(pipe(lpr)). | % Start writing to the printer. | 
Another example of using the pipe/1 construct is shown below.41As of version 5.3.15, the pipe construct is supported in the MS-Windows version, both for plcon.exe and plwin.exe. The implementation uses code from the LUA programming language (http://www.lua.org). Note that the pipe/1 construct is not part of Prolog's standard I/O repertoire.
getwd(Wd) :-
        seeing(Old), see(pipe(pwd)),
        collect_wd(String),
        seen, see(Old),
        atom_codes(Wd, String).
collect_wd([C|R]) :-
        get0(C), C \== -1, !,
        collect_wd(R).
collect_wd([]).
Unlike Edinburgh Prolog systems, telling/1 and seeing/1 do not return the filename of the current input/output, but the stream-identifier, to ensure the design pattern below works under all circumstances.42Filenames can be ambiguous and SWI-Prolog streams can refer to much more than just files.
        ...,
        telling(Old), tell(x),
        ...,
        told, tell(Old),
        ...,
The predicates tell/1 
and see/1 
first check for user, the
pipe(command) and a stream-handle. Otherwise, if the 
argument is an atom it is first compared to open streams associated to a 
file with exactly the same name. If such a stream, created 
using
tell/1 
or see/1 
exists, output (input) is switch to the open stream. Otherwise a file 
with the specified name is opened.
The behaviour is compatible with Edinburgh Prolog. This is not without problems. Changing directory, non-file streams, multiple names referring to the same file easily lead to unexpected behaviour. New code, especially when managing multiple I/O channels should consider using the ISO I/O predicates defined in section 4.16.1.
user is returned if the current input is the 
stream user_input to improve compatibility with traditional 
Edinburgh I/O. See the introduction of
section 4.16.2 for details.user is returned if the current output is the 
stream user_output to improve compatibility with 
traditional Edinburgh I/O. See the introduction of
section 4.16.2 for details.The predicates below can be used for switching between the implicit- and the explicit stream based I/O predicates.
Applications should generally avoid creating atoms by breaking and concatenating other atoms as the creation of large numbers of intermediate atoms generally leads to poor performance, even more so in multi-threaded applications. This predicate supports creating difference-lists from character data efficiently. The example below defines the DCG rule term/3 to insert a term in the output:
term(Term, In, Tail) :-
        with_output_to(codes(In, Tail), write(Term)).
?- phrase(term(hello), X).
X = [104, 101, 108, 108, 111]