http://qs1969.pair.com?node_id=11139159

abdan has asked for the wisdom of the Perl Monks concerning the following question:

How can we check Perl input-output handle e.g. open R,"$file" is defined or existing, as it's needed or useful to be tested later ?

Replies are listed 'Best First'.
Re: File input-output handle defined or no determination
by jwkrahn (Monsignor) on Nov 27, 2021 at 02:16 UTC
    $ perldoc -f fileno fileno FILEHANDLE Returns the file descriptor for a filehandle, or undefined + if the filehandle is not open. If there is no real file descripto +r at the OS level, as can happen with filehandles connected to memo +ry objects via "open" with a reference for the third argument +, -1 is returned.
Re: File input-output handle defined or no determination
by Marshall (Canon) on Nov 27, 2021 at 03:33 UTC
    Your code,  open R,"$file" will by default open global symbol R for reading.

    Better is:
    open my $R, '<', "$file" or die "your specific message $!";
    Use a lexical variable, "my" instead of a package global, explicitly say this is for reading (or writing), print an error message and exit your program (i.e. die) if the open does not succeed.

    For a disk file, you can assume that all subsequent "prints" to that filehandle will work. There is no need to check if the file handle is still open, it is.

    There are boundary cases where the write to a file will fail (like filesystem full) and there are situations where a connection to a network file socket will be lost. Handling those cases are beyond what you are asking about.

    Update: While jwkrahn's answer is factually correct, this doesn't have much meaning in practical Perl code. When you open a file handle, you should check that the open worked, and if it did, thereafter you should assume that the file handle is still open. At low level C code, there is such a thing as a fileno. But you will very likely will never ever encounter or need this number in Perl. Just because a file handle is "open", that does not mean that actually using it to read or write will work. At the end of the day, "the proof is in the pudding" - you have to actually use the filehandle in order to know if it indeed works to get or send data.

    A reply falls below the community's threshold of quality. You may see it by logging in.
Re: File input-output handle defined or no determination
by syphilis (Archbishop) on Nov 28, 2021 at 02:22 UTC
    How can we check Perl input-output handle

    A few years back I wrote FileHandle::Fmode. It hasn't been updated in the last 7 years, but I think it still functions correctly and, IIUC, it provides the sort of info you're seeking.
    Here's an excerpt from the POD that documents the functions that it provides:
    $bool = is_FH($fh); $bool = is_FH(\*FH); This is just a (more intuitively named) alias for is_arg_ok(). Returns 1 if its argument is an open filehandle. Returns 0 if its argument is something other than an open filehandle +. $bool = is_arg_ok($fh); $bool = is_arg_ok(\*FH); Returns 1 if its argument is an open filehandle. Returns 0 if its argument is something other than an open filehandle +. Arguments to the following functions must be open filehandles. If any of those functions receive an argument that is not an open filehandle then the function dies with an appropriate error message. To ensure that your script won't suffer such a death, you could first check by passing the argument to is_FH(). Or you could wrap the function call in an eval{} block. Note that it may be possible that a filehandle opened for writing may become unwritable - if (eg) the disk becomes full. I don't know how the below functions would be affected by such an event. I suspect that they would be unaware of the change ... but I haven't actually checked. $bool = is_R($fh); $bool = is_R(\*FH); Returns true if the filehandle is readable. Else returns false. $bool = is_W($fh); $bool = is_W(\*FH); Returns true if the filehandle is writable. Else returns false. $bool = is_RO($fh); $bool = is_RO(\*FH); Returns true if the filehandle is readable but not writable. Else returns false. $bool = is_WO($fh); $bool = is_WO(\*FH); Returns true if the filehandle is writable but not readable. Else returns false. $bool = is_RW($fh); $bool = is_RW(\*FH); Returns true if the filehandle is both readable and writable. Else returns false. $bool = is_A($fh); $bool = is_A(\*FH); Returns true if the filehandle was opened for appending. Else returns false. Not currently implemented on Win32 with pre-5.6.1 versions of perl ( +and dies with appropriate error message if called on such a platform).
    Cheers,
    Rob