Perl打开文件问题

发布于 2024-08-28 17:43:23 字数 442 浏览 5 评论 0 原文

我在尝试从文件打印时遇到一些问题。有什么想法吗?谢谢

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.

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/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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

追风人 2024-09-04 17:43:23
  1. 此讨论解决了该消息的技术原因。该线程的相关信息是这样的:

    来自 open(2) 联机帮助页:

    调用成功后,返回的文件描述符为
    当前未为进程打开的最低文件描述符。

    <块引用>

    但是 STDOUT 仍然指的是
    文件句柄#1。这个警告可能是
    有用。尽管有人可以争辩说
    进一步使用 STDOUT 作为输出
    文件句柄将触发警告
    嗯...

    因此,总而言之,您关闭了 STDOUT(文件描述符 1),并且您的文件将以 FD#1 的形式打开。这是由于 open() 的 属性所致。

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

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

    open(OUTFILE,">/home/int420_101a05/shttpd/htdocs/receipt.html")
       || die“无法打开:$!”; 
    打印 OUTFILE“数据”;
    关闭(输出文件);
    正如
  3. 要从子例程打印到文件句柄,只需将文件句柄作为参数传递

    最好的方法是创建一个 IO::File 对象并传递该对象

    my $filehandle = IO::File->new(">$filename") ||死“错误:$!”;
    mySub($文件句柄);
    
    子我的子{
     我的 $fh = 转变;
     打印$fh“东西”|| die“无法打印$!”;    
    }
    
    
    

    您还可以将特定文件句柄设置为默认文件句柄,以便默认使用 select 打印该文件句柄,但这要脆弱得多,应该避免使用 IO::File 解决方案.

  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.

行雁书 2024-09-04 17:43:23

如果您想临时更改标准输出,请使用 select 内置函数。另一种选择是首先本地化 typeglob:

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

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";
}
上课铃就是安魂曲 2024-09-04 17:43:23

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文