开发者

Perl open file problem

开发者 https://www.devze.com 2022-12-26 06:52 出处:网络
I am having some trouble trying to print from a file. Any ideas? Thanks open(STDOUT,\">/home/int420_101a05/shttpd/htdocs/receipt.html\");

I am having some trouble trying to print from a file. Any ideas? Thanks

open(STDOUT,">/home/int420_101a05/shttpd/htdocs/receipt.html"); 
#Results of a sub-routine
&printReceipt; 
close(STDOUT);

open(INF,"/home/int420_101a05/shttpd/h开发者_开发问答tdocs/receipt.html"); $emailBody = <INF>; 
close(INF); 
print $emailBody;

ERRORS: Filehandle STDOUT reopened as INF only for input at ./test.c line 6. 
print() on closed filehandle STDOUT at ./test.c line 9.


  1. This discussion addresses the technical reason for the message. Relevant info from the thread is this:

    From open(2) manpage:

    When the call is successful, the file descriptor returned will be the lowest file descriptor not currently open for the process.

    But STDOUT still refers to the filehandle #1. This warning could be useful. Although one can argue that further uses of STDOUT as an output filehandle will trigger a warning as well...

    So, to summarize, you closed STDOUT (file descriptor 1) and your file will be open as FD#1. That's due to open()'s properties.

  2. As other have noted, the real reason you're having this problem is that you should not use STDOUT for printing to a file unless there's some special case where it's required.

    Instead, open a file for writing using a new file handle:

    open(OUTFILE,">/home/int420_101a05/shttpd/htdocs/receipt.html")
       || die "Could not open: $!"; 
    print OUTFILE "data";
    close(OUTFILE);
    
  3. To print to filehandle from subroutine, just pass the file handle as a parameter.

    The best way of doing so is to create an IO::File object and pass that object around

    my $filehandle = IO::File->new(">$filename") || die "error: $!";
    mySub($filehandle);
    
    sub mySub {
     my $fh = shift;
     print $fh "stuff" || die "could not print $!";    
    }
    

    You can also set a particular filehandle as a default filehandle to have print print to that by default using select but that is a LOT more fragile and should be avoidded in favor of IO::File solution.


If you want to temporarily change the standard output, use the select builtin. Another option is to localize the typeglob first:

{
    local *STDOUT;
    open STDOUT, '>', 'outfile.txt' or die $!;
    print "Sent to file\n";
}


Don't try to open the STDOUT handle. If you want to print to STDOUT, just use print (with no filehandle argument). If you want to print to something other than STDOUT, use a different name.

0

精彩评论

暂无评论...
验证码 换一张
取 消