2009-05-30 30 views
11

Tôi gặp lỗi này trong khi thực thi tập lệnh Perl của mình. Xin vui lòng, cho tôi biết làm thế nào để khắc phục lỗi này trong Perl.Làm cách nào để giải quyết lỗi "print() khi đóng filehandle" trong Perl?

print() on closed filehandle MYFILE 

Đây là mã mà là đưa ra các lỗi:

sub return_error 
{ 
    $DATA= "Sorry this page is corrently being updated...<p>"; 
    $DATA.= "<A href=\"javascript:history.go(-1)\"> Back </A>"; 
    open(MYFILE,">/home/abc/xrt/sdf/news/top.html"); 
    print MYFILE $DATA; 
    close(MYFILE); 
    exit; 
} 

Tôi hy vọng rằng bây giờ tôi rõ ràng hơn.

+1

Tiêu đề của bài đăng phải được chỉnh sửa. Có vẻ như đó là một lỗi 'trong Perl'! –

+1

sẽ thuận tiện nếu cảnh báo của perl "print() trên filehandle đóng" tin nhắn cũng đề nghị kiểm tra filehandle có thể được mở hoặc không –

Trả lời

29

Bạn muốn thực hiện một số hành động trên MYFILE sau khi bạn (hoặc bản thân thông dịch viên do lỗi) đã đóng.

Theo mẫu mã của bạn, sự cố có thể là open không thực sự mở tệp, tập lệnh có thể không có quyền ghi vào tệp.

Thay đổi mã của bạn để sau để xem nếu có một lỗi:

open(MYFILE, ">", "/home/abc/xrt/sdf/news/top.html") or die "Couldn't open: $!"; 

Cập nhật

ysth chỉ ra rằng -w là không thực sự giỏi kiểm tra nếu bạn có thể ghi vào tập tin , nó chỉ 'kiểm tra xem một trong các cờ có liên quan trong chế độ được đặt'. Hơn nữa, brian d foy nói với tôi rằng điều kiện tôi đã sử dụng không tốt trong việc xử lý lỗi. Vì vậy, tôi đã xóa mã gây hiểu lầm. Sử dụng mã ở trên để thay thế.

+1

Tôi muốn mở ba đối số: mở (MYFILE, '>', $ file) ... – Svante

+0

@Svante: cảm ơn, Brad đã sửa chữa điều đó :) –

+0

-w không kiểm tra xem bạn có thể ghi vào tệp hay không, nó kiểm tra xem một trong các cờ có liên quan trong chế độ đã được đặt chưa. Điều này có thể tạo ra cả hai dương tính giả và âm bản sai. Bạn đang tốt hơn rất nhiều chỉ cố gắng để mở nó cho văn bản và phát hiện một lỗi mở. – ysth

1

Một nơi nào đó trong bạn kịch bản, bạn sẽ được làm một cái gì đó như:

open MYFILE, "> myfile.txt"; 
# do stuff with myfile 
close MYFILE; 
print MYFILE "Some more stuff I want to write to myfile"; 

Dòng cuối cùng sẽ ném ra một lỗi vì myfile đã bị đóng cửa.

Cập nhật

Sau khi nhìn thấy mã của bạn, nó trông giống như các tập tin bạn đang cố gắng để viết thư cho không thể mở được ở nơi đầu tiên. Vì những người khác đã đề cập đến việc thử làm một việc gì đó như:

open MYFILE, "> myfile.txt" or die "Can't open myfile.txt: $!\n" 

Nên cung cấp cho bạn một số phản hồi về lý do bạn không thể mở tệp.

+0

tôi cũng có đoạn mã của tôi ............... vui lòng xem và giúp tôi giải pháp –

3

này:

open(MYFILE,">/home/abc/xrt/sdf/news/top.html"); 

Trong modern Perl, nó có thể được viết như sau:

open(my $file_fh, ">", "/home/abc/xrt/sdf/news/top.html") or die($!); 

Bằng cách này bạn sẽ có được một biến $ giới hạn trong phạm vi, không có "kinh doanh sôi nổi" nếu bạn có tên tập tin lạ (ví dụ như bắt đầu với ">") và xử lý lỗi (bạn có thể thay thế chết bằng cảnh báo hoặc với mã xử lý lỗi).

Khi bạn đóng $ file_fh hoặc đơn giản là nằm ngoài phạm vi, bạn không thể in được nữa.

12

Dường như cuộc gọi open không thành công. Bạn nên luôn luôn kiểm tra trạng thái khi mở tệp bằng tay.

my $file = '/home/abc/xrt/sdf/news/top.html'; 
open(MYFILE, ">$file") or die "Can't write to file '$file' [$!]\n"; 
print MYFILE $DATA; 
close MYFILE; 

Nếu mở không thành công, biến được tạo sẵn $! (a.k.a. $ OS_ERROR) sẽ chứa thông báo lỗi do OS-depededant, ví dụ: "Permission denied"

Nó cũng thích hợp hơn (đối với phiên bản không cổ xưa của Perl) để sử dụng hình thức ba đối số của open và filehandles từ vựng:

my $file = '/home/abc/xrt/sdf/news/top.html'; 
open(my $fh, '>', $file) or die "Can't write to file '$file' [$!]\n"; 
print {$fh} $DATA; 
close $fh; 
+0

Tôi biết điều đó ở PBP, nhưng tôi không thể quen với giao diện của 'print {$ fh} $ DATA' để in thành tệp thủ công. Nó có vẻ sai. – Telemachus

3

Kiểm tra xem mở làm việc

if(open(my $FH, ">", "filename") || die("error: $!")) 
{ 
    print $FH "stuff"; 
    close($FH); 
} 
+1

Bạn không cần cấu trúc if(). Khi nó sai, bạn đã chết. :) –

6

Một giải pháp thay thế để nói or die là sử dụng autodie pragma:

#!/usr/bin/perl 

use strict; 
use warnings; 
use autodie; 

open my $fh, "<", "nsdfkjwefnbwef"; 

print "should never get here (unless you named files weirdly)\n"; 

Đoạn mã trên tạo ra các lỗi sau (trừ khi một tập tin có tên nsdfkjwefnbwef tồn tại trong thư mục hiện hành):

Can't open 'nsdfkjwefnbwef' for reading: 'No such file or directory' at example.pl line 7 
2

Nếu bạn sử dụng một myfile biểu tượng toàn cầu như filehandle của bạn, chứ không phải là một địa phương từ vựng ($ myfile), bạn sẽ luôn gặp sự cố nếu chương trình của bạn đa luồng, ví dụ nếu nó đang chạy qua mod_perl. Một quá trình có thể được đóng tập tin tay trong khi một quá trình khác đang cố gắng ghi vào nó. Sử dụng $ myfile sẽ tránh vấn đề này vì mỗi cá thể sẽ có bản sao cục bộ riêng của nó, nhưng bạn vẫn sẽ gặp phải các vấn đề mà một tiến trình có thể ghi đè lên dữ liệu mà người khác đang viết. Sử dụng flock() để khóa tập tin trong khi ghi vào nó.

3

Tôi gặp sự cố này khi tệp của tôi được đặt thành READ-ONLY.

Kiểm tra điều này, trước khi bỏ cuộc! :)

Các vấn đề liên quan