XSB has various low-level routines that support input and output, at both the term level and the character level. Unlike the standard Prolog stream I/O, the low-level routines use XSB I/O ports to refer to files. XSB I/O ports should not be confused with the file descriptors used by the OS Both are small integers, but they refer to different things. However, the OS file descriptors are objects returned by the C open function; XSB I/O ports indices into the internal XSB table of open files. The OS does not know about XSB I/O ports, while XSB (obviously) does know about the OS file descriptors. An OS file descriptor (which can be returned by some predicates, such as pipe_open/2, can be promoted to XSB I/O port using the predicate fd2ioport/2.
Typically XSB opens files for buffered I/O (whether using the standard stream I/O predicates or the predicates described here), so XSB I/O ports internally refer to FILE data structures (those returned by the C fopen function).
XSB I/O ports should not be confused with I/O streams used by the standard Prolog predicates, like see/1, tell/1, etc. The streams are higher-level objects associated with atom constants and which use I/O ports underneath. An I/O port can be promoted to an I/O stream using the predicate ioport2iostream/2, described below.
When it starts, XSB opens a number of standard I/O ports that it uses to print results, errors, debugging info, etc. The descriptors are described in the file prolog_includes/standard.h. This file provides the following symbolic definitions:
#define STDIN 0 #define STDOUT 1 #define STDERR 2 #define STDWARN 3 /* output stream for xsb warnings */ #define STDMSG 4 /* output for regular xsb messages */ #define STDDBG 5 /* output for debugging info */ #define STDFDBK 6 /* output for XSB feedback (prompt/yes/no/Aborting/answers) */ #define AF_INET 0 /* XSB-side socket request for Internet domain */ #define AF_UNIX 1 /* XSB-side socket request for UNIX domain */In addition, the file
emu/file_modes_xsb.h
provides the definitions
for the file opening modes:
#define OREAD 0 /* open for read */ #define OWRITE 1 /* open for write */ #define OAPPEND 2 /* open for append */ #define OSTRINGR 3 /* open string for reading */ #define OSTRINGW 4 /* open string for writing (not implemented) */These definitions can be used in user programs, if the following is provided at the top of the source file:
compiler_options([xpp_on]). #include "standard.h" #include "file_modes_xsb.h"(Note: the XSB preprocessor is not invoked on clauses typed into an interactive XSB session, so the above applies only to programs loaded from a file using consult and such.)
The old-style mode specification, 0 (OREAD), 1 (OWRITE), 2 (OAPPEND), or 3 (OSTRING), is also supported.
| ?- file_reopen('/dev/null', w, 3, Error).redirects all warnings to the Unix black hole.
On success, RetCode is 0; on error, the return code is negative.
| ?- file_clone(10,3,_).causes all messages sent to XSB standard warnings port to go to file foo.bar. While this could be also done with file_reopen, there are things that only file_clone can do:
| ?- file_clone(1,10,_).This means that I/O port 10 now becomes clone of standard output. So, all subsequent I/O will now go to standard output instead of foo.bar.
On success, RetCode is 0; on error, the return code is negative.
Term is a term (e.g., args(X,Y,Z)) whose arguments will be unified with the field values read in. (The functor symbol of Term is ignored.) Special syntactic sugar is provided for the case when the format string contains only one format specifier: If Term is a variable, X, then the predicate behaves as if Term were arg(X).
If the number of arguments exceeds the number of format specifiers, a warning is produced and the extra arguments remain uninstantiated. If the number of format specifiers exceeds the number of arguments, then the remainder of the format string (after the last matching specifier) is ignored.
Note that floats do not unify with anything. Ret must be a variable and it will be assigned a return value by the predicate: a negative integer if end-of-file is encountered; otherwise the number of fields read (as returned by scanf.)
fmt_read cannot read strings (that correspond to the %s format specifier) that are longer than 16K. Attempting to read longer strings will cause buffer overflow. It is therefore recommended that one should use size modifiers in format strings (e.g., %2000s), if such long strings might occur in the input.
In addition to the usual C conversion specifiers, %S is also allowed. The corresponding argument can be any Prolog term. This provides an easy way to print the values of Prolog variables, etc. Also %! is supported and indicates that the corresponding argument is to be ignored and will generate nothing in the output.
Another difference with C is that, unlike most C compilers, XSB insists that a single % in the format string signifies format conversion specification. (Some C compilers might output % if it is not followed by a valid type conversion spec.) So, to output % you must type %%.
Format can also be an atom, but then escape sequences are not recognized.
Term is a term (e.g., args(X,Y,Z)) whose arguments will be output. The functor symbol of Term is ignored.
Special syntactic sugar is provided for the following cases: If Term is a variable, X, then it is ignored and only the format string is printed. If Term is a string, integer or a float, then it is assumed that this is the only argument to be printed, i.e., it is equivalent to specifying arg(Term).
If the number of format specifiers is greater than the number of arguments to be printed, an error is issued. If the number of arguments is greater, then a warning is issued.
fmt_write
, is
recognized. The result is available in String. Fmt is a
string or an atom that represents the format, as in
fmt_write.
If the number of format specifiers is greater than the number of arguments to be printed, an error is issued. If the number of arguments is greater, then a warning is issued.
fmt_write_string requires that the printed size of each argument (e.g., X,Y,and Z above) must be less than 16K. Longer arguments are cut to that size, so some loss of information is possible. However, there is no limit on the total size of the output (apart from the maximum atom size imposed by XSB).
This predicate fails on reaching the end of file.
file_read_line
.
file_read_line_atom/2
, but IOport is not required.
The file being read is the one previously opened with see/1.
file_read_line_atom
, but the line read from
the input is converted into a list of characters.
This predicate is much more efficient than fget_line/3
(see below), and is recommended when speed is important.
This predicate fails on reaching the end of file.
file_read_line_list/3
, but IOport is not required.
The file being read is the one previously opened with see/1.
This predicate is obsolete and
file_read_line_list
should be used instead.
\n
, are
recognized if String is a character list, but are output as is if
String is an atom.
file_write_line/3
, but output goes to the currently open
output stream.
file_getbuf
.
Note: because XSB does not have an atom table garbage collector yet, this predicate should not be used to read large files.
file_getbuf_atom/4
, but reads from the currently open input stream
(using see/1). This predicate always
succeeds. It does not distinguish between a file error and end of file.
You can determine if either of these conditions has happened by verifying
that
.
file_getbuf_atom/4
, but CharList is instantiated to a list
of characters that represent the string read from the input.
file_getbuf_list/3
, but reads from the currently open input stream
(i.e., with see/1).
file_putbuf/3
, but output goes to the currently open output stream.
_$newstream_#123
.