2010-04-12 150 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