我在尝试从文件打印时遇到了一些麻烦。有任何想法吗?感谢
open(STDOUT,">/home/int420_101a05/shttpd/htdocs/receipt.html");
#Results of a sub-routine
&printReceipt;
close(STDOUT);
open(INF,"/home/int420_101a05/shttpd/htdocs/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.
答案 0 :(得分:4)
This discussion addresses the technical reason for the message。该主题的相关信息是:
从open(2)联机帮助页:
当调用成功时,返回的文件描述符将是 当前未为该进程打开的最低文件描述符。
但STDOUT仍然指的是 文件句柄#1。这个警告可能是 有用。虽然有人可以争辩 进一步使用STDOUT作为输出 filehandle将触发警告 良好...
因此,总而言之,您关闭了STDOUT(文件描述符1),您的文件将作为FD#1打开。这是由于open()'s
属性。
正如其他人所说,你遇到这个问题的真正原因是你不应该使用STDOUT来打印文件,除非有一些特殊情况需要它。
相反,使用新文件句柄打开要写入的文件:
open(OUTFILE,">/home/int420_101a05/shttpd/htdocs/receipt.html") || die "Could not open: $!"; print OUTFILE "data"; close(OUTFILE);
要从子程序打印到文件句柄,只需将文件句柄作为参数传递。
这样做的最佳方法是创建一个IO::File
对象并传递该对象
my $filehandle = IO::File->new(">$filename") || die "error: $!"; mySub($filehandle); sub mySub { my $fh = shift; print $fh "stuff" || die "could not print $!"; }
您还可以将特定的文件句柄设置为默认文件句柄,默认情况下使用select
将打印件打印到该文件句柄,但这样做更加脆弱,应该避免使用IO :: File解决方案。
答案 1 :(得分:1)
如果要暂时更改标准输出,请使用select内置。另一个选择是首先本地化typeglob:
{
local *STDOUT;
open STDOUT, '>', 'outfile.txt' or die $!;
print "Sent to file\n";
}
答案 2 :(得分:0)
不要尝试打开STDOUT手柄。如果要打印到STDOUT,只需使用print
(没有filehandle参数)。如果要打印到STDOUT以外的其他名称,请使用其他名称。