
Beman Dawes wrote:
If the is_* functions return false, rather than throwing, then testing for the negative of a is_* function becomes unreliable.
On the contrary, it becomes reliable. It's currently undefined.
Does !is_directory( "foo" ) mean that "foo" is a file, or is is just missing?
!is_directory( "foo" ) means that "foo" is not a directory, i.e. directory operations on "foo" will fail. It cannot be used as a substitute for "is a file", for any reasonable definition of "is a file".
The programmer would have to write exists("foo") && is_accessible("foo") && !is_directory("foo"). That could be simplified by providing an is_file() function (as suggested by Jeff Garland recently), but then we have to define exactly what a file is. Is a socket a file? Is a device a file? Or what POSIX calls a "regular file"? How does that translate to Windows?
It depends on your definition of "file". In general, is_X( "foo" ) should return true when "foo" can be treated as a X, that is, you can call X-related functions on "foo". One example could be is_data_stream( "foo" ), which would mean that you can fopen( "foo" ) and then fread it. Or is_seekable_stream, which also includes fseek. Note that on platforms where a directory can be opened with fopen, is_directory and is_data_stream will both return true. The translation of is_regular_file to Windows is trivial, if a bit time-consuming: enumerate all properties of a POSIX regular file (that are observable to us); everything that matches this description is a "regular file", not only on Windows, but on an arbitrary file system.