0

我想将文件句柄存储到全局哈希并在子例程中读取()它而不显示 CGI 对象,但我发现它不起作用(导致输出文件大小为零)。

这是简化的 perl 代码:

#!/usr/local/bin/perl

use CGI;
use vars qw(%in);

&init_hash;
$fname = &process_uploaded_file if($in{'upfile'});
$fsize = -s $fname;

print "Content-Type: text/plain\r\n\r\n";
print "in{'upfile'}=",$in{'upfile'},"\r\n";
print "in{'desc'}=",$in{'desc'},"\r\n";
print "fname=",$fname,"\r\n";
print "fsize=",$fsize,"\r\n";

sub init_hash{
    my $q = new CGI;
    $in{'desc'} = $q->param('desc');
    $in{'upfile'} = $q->param('upfile');
    $in{'upfh'} = $q->upload('upfile') if($in{'upfile'});
}

sub process_uploaded_file{
    my $fname = time.'.bin';
    open(OUT,'>',$fname) || die('open file failed');
    while(my $read = read($in{'upfh'}, my $buff, 4096)){
        print OUT $buff;
    }
    close(OUT);
    eval { close($in{'upfh'}); };
    return $fname;
}

编辑:我应该提供 perl 和 cgi.pm 版本。Perl 版本:这是为 MSWin32-x86-multi-thread 构建的 perl 5,版本 12,subversion 2 (v5.12.2)(带有 8 个已注册补丁,请参阅 perl -V 了解更多详细信息)$CGI::VERSION='3.50' ;

4

1 回答 1

2

你的代码有很多错误。

首先是您的问题:您正在尝试优化不应该进行优化的地方。CGI 对象的临时文件在您实际访问它们之前被删除。当您延长 CGI 对象的生命周期时,您的代码应该可以工作,例如通过将其添加到%in散列中。


  • 总是use strict; use warnings;。没有任何借口。
  • 全局变量用our. varspragma 是一个历史产物。但是请不要使用全局变量,因为它们在这里是不必要的。
  • 不要调用函数,&foo除非你能告诉我这到底是做什么的。直到你掌握了这些知识:foo()
  • 使用headerCGI 对象的方法写入头文件:$q->header('text/plain').
  • \n可能不是你想的那样。如果当前应用了 PerlIO 层,请执行 abinmode STDOUT以删除它。:crlf虽然等同于\r\n,但写起来可能更清楚地\015\012表明您关心实际字节。
  • 你可以将变量插入字符串,你知道的。您还可以print通过设置指定要在每个之后附加的字符串$\

    {
      local $\ = "\015\012";
      print "in{'upfile'}=$in{'upfile'}";
      print "in{'desc'}=$in{'desc'}";
      print "fname=$fname";
      print "fsize=$fsize";
    }
    
  • 不要使用裸字文件句柄。而不是open OUT, "<", $fname你应该open my $outfh, "<", $fname
  • 你为什么把一个close放在一个eval?我不明白这应该如何die
于 2013-08-03T07:01:46.447 回答