2013-08-03 1 views
0

Я хотел бы сохранить дескриптор файла в глобальный хеш и прочитать() его в подпрограмме без выявления объекта CGI, но я обнаружил, что он не работает (в результате получается выходной файл нулевого размера).CGI.pm: дескриптор файла в глобальном хеше потерян между подпрограммами?

Вот упрощенный код 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; 
} 

EDIT: я должен предоставить Perl и CGI.pm версии. Версия для Perl: это perl 5, версия 12, subversion 2 (v5.12.2), построенная для MSWin32-x86-многопотоковых (с 8 зарегистрированными исправлениями, см. Perl -V для более подробной информации) $ CGI :: VERSION = «3,50»;

+0

Я думаю, вам нужно проверить, читается ли информация из файла $ в {'upfh'} –

+0

@KostiaShiian, но файл создан и доступен для записи. Если я добавлю содержимое process_uploaded_file к init_hash и закомментирую строку 7, он будет работать. – Roy

ответ

2

В коде есть так много ошибок.

Во-первых, ваша проблема: вы пытаетесь оптимизировать, когда оптимизация не вызвана. И временные файлы объекта CGI удаляются, прежде чем вы действительно получите к ним доступ. Ваш код должен работать, когда вы продлеваете срок службы объекта CGI, например. добавив его в хэш-код %in.


  • Всегда use strict; use warnings;. Нет оправданий.
  • Глобальные переменные объявлены our. Прагма vars является историческим артефактом. Но, пожалуйста, не используйте глобальные переменные, так как здесь они не нужны.
  • Не вызывайте такие функции, как &foo, если вы не можете мне сообщить, что точно это делает. Пока у вас нет таких знаний: foo().
  • Используйте метод header объекта CGI для записи заголовков: $q->header('text/plain').
  • \n Возможно, это не так, как вы думаете. Сделайте binmode STDOUT, чтобы удалить слой PerlIO :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"; 
    } 
    
  • Не используйте bareword дескрипторы файлов. Вместо open OUT, "<", $fname вы должны open my $outfh, "<", $fname.
  • Почему вы положили один close в eval? Я не вижу, как это должно быть die.
+0

Спасибо. Добавление $ q to% in делает трюк. Этот код является устаревшим кодом (cca 2003), который хорошо работает на старом сервере. – Roy

Смежные вопросы