2010-04-12 134 views
2

我在尝试从文件打印时遇到了一些麻烦。有任何想法吗?谢谢Perl打开文件问题

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

看起来你不需要临时文件,如果你只是打算把它打印到标准输入。 – 2010-04-13 07:06:34

+0

@brian - 基于上面的骨架代码的好点。我猜测第二块只是用于记录/验证,主要目标是在磁盘上获得'receipt.html'。亚历克斯 - 请你澄清一下吗? – DVK 2010-04-13 10:22:10

回答

4
  1. This discussion addresses the technical reason for the message。从线程相关的信息是这样的:

    从开放(2)手册页:

    当调用成功,返回值将是 最低的文件描述符目前没有开放的进程的文件描述符。

    但STDOUT仍然指 文件句柄#1。此警告可能是 有用。虽然人们可以争辩STDOUT的是 进一步用途为输出 文件句柄将触发警告的 以及...

    所以,总结一下,您关闭标准输出(文件描述符1),你的文件将被打开作为FD#1。这是由于open()'s属性。

  2. 正如其他人已经指出的,你遇到这个问题的真正原因是你不应该使用STDOUT打印到文件,除非有一些特殊情况需要它。

    相反,打开一个文件使用一个新的文件句柄写:

     
    open(OUTFILE,">/home/int420_101a05/shttpd/htdocs/receipt.html") 
        || die "Could not open: $!"; 
    print OUTFILE "data"; 
    close(OUTFILE); 
    
  3. 打印从子程序文件句柄,只要传递文件句柄作为参数

    这样做的最好的方法是创建一个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解决方案。

+0

事情是,我想打印一个子程序的结果......有什么办法可以完成这个? – AlexBrand 2010-04-12 15:23:37

+2

你想要做的是'选择FILEHANDLE'。 “select”调用将新的文件句柄设置为打印调用的默认目的地。 – 2010-04-12 15:25:57

+0

@alexBrand - 增加了关于如何在子程序中正确打印的信息 – DVK 2010-04-12 15:27:03

0

不要试图打开STDOUT句柄。如果你想打印到STDOUT,只需使用print(没有文件句柄参数)。如果您想打印到STDOUT以外的其他内容,请使用其他名称。

1

如果要暂时更改标准输出,请使用内建的select。另一个选择是首先本地化typeglob:

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

事情是我试图打印一个子程序的结果到文件中...我只是改变了代码..对不起 – AlexBrand 2010-04-12 15:18:17