No matter what programming language you are using, all multiple-access file systems have the problem that the system may correctly report that a file does exist, and then when you attempt to use it you may find that it does not, because someone has deleted or renamed it in the meantime.
The operations below can help you avoid problems, but in the final analysis, the only way to tell whether you can open a file is to try to open it.
file_exists(
+FileName)
file_exists/1
succeeds if a
file of that name exists. If there is something of that
name, but it is a directory, file_exists/1
fails.
You need sufficient rights to the file to be able to determine whether it
is a directory (see stat(2)
).
Named pipes and devices are accepted as files.
file_exists(
+FileName,
+Permissions)
exists
read
write
access(2)
file_exists/2
succeeds when there is a file (not a directory)
named FileName and you have each of the Permissions you named.
If Permission is an integer, it is interpreted the
way that the argument to the system call access(2)
is interpreted, namely (the file must exist)
+ 1 * ('execute' permission is wanted) + 2 * ('write' permission is wanted) + 4 * ('read' permission is wanted)>
This is allowed so that a C programmer who is used to writing
if (!access(FileName, 6)) { can_read_and_write(FileName); } else { cannot_access_file(FileName); }
can write
( file_exists(FileName, 6) -> can_read_and_write(FileName) ; /* otherwise */ cannot_access_file(FileName) )
We recommend, however, that you code this example as
( file_exists(FileName, [read,write]) -> can_read_and_write(FileName) ; /* otherwise */ cannot_access_file(FileName) )
Under operating
systems that do not support version numbers (as UNIX and Windows do not),
file_exists/2
could fail (because there is no such FileName)
and can_open_file/2
could succeed (because you are allowed
to create one). Conversely, file_exists/2
could succeed
(because there is such a FileName) and can_open_file/2
fail
(because you have so many files open that you cannot open another).
file_must_exist(
+FileName)
file_exists(
FileName)
succeeds;
otherwise, it raises an error exception.
| ?- file_must_exist(fred). ! Existence error in file_must_exist/1 ! file fred does not exist ! O/S error : No such file or directory ! goal: file_must_exist(fred)
file_must_exist(
+FileName,
+Permission)
file_exists(
FileName,
Permission)
succeeds;
otherwise, it raises an error exception.
| ?- unix(system('ls -l files.o')), file_must_exist('files.o', write). -r--r--r-- 1 ok 746 Jan 24 17:58 files.o ! Permission error: cannot access file 'foo.o' ! O/S error : Permission denied ! goal: file_must_exist('foo.o',write)
can_open_file(
+FileName,
+Mode,
+Quiet)
read
, write
, or append
,
just as for the open/3
command. can_open_file/2
fails quietly
if the file cannot be opened. The Quiet parameter controls the
raising of an error exception when the file cannot be opened: if
Quiet is fail
, can_open_file/3
fails quietly, whereas if
Quiet is warn
, it raises an error exception.
If Mode is
read
append
write
append
This predicate actually attempts to open the file. It will, for
example, create a file in order to determine whether it can
create it. But if that happens, it immediately deletes the file
again, so there should be no permanent effect on the file system.
can_open_file(
+FileName,
+Mode)
can_open_file(
FileName,
Mode, fail)
.
open_file(
+FileName,
+Mode,
-Stream)
open/3
(which is
described in the reference pages), except that it
always raises an error exception if it cannot open
the file, and is not sensitive to the fileerrors
flag.
current_dec10_stream(?FileName, ?See_or_Tell)
see
and FileName is a file that was opened by
see(
FileName)
and has not yet been closed, or when See_or_Tell
is tell
and FileName is a file that was opened by
tell(
FileName)
and has not yet been closed. It is a version of
current_stream/3
, which just tells you about the Dec-10-compatible
streams. It relies on two facts: (1) all the streams you opened
are in the current_stream/3
table. (2) seeing/1
(telling/1
) return an
atom if and only if the current input (output) stream was opened by
see/1
(tell/1
), and the atom it returns is the one given to
see/1
(tell/1
).
close_all_streams
None of the predicates described in this section is affected by
the fileerrors
flag. Indeed, they exist so that you can check
for errors before they happen.
See the summary description of library(ask)
(lib-uin) for two useful
predicates that use can_open_file/3
.