2010-03-24 6 views
1

Моя функция загрузки выглядит следующим образом:Как сохранить загруженные двоичные файлы в программе Perl FastCGI?

sub Upload_File{ 
my ($file, $mime, $description) = @_; 
my $file_name = param('filename'); 

my $data; 

$file = UnTaint($file); 

    if ($mime =~ /text/) { 
      sysopen(VAULT, "$path/$file", O_RDWR | O_EXCL | O_CREAT | O_TEXT) or die "couldn't create $file for R/W: $!\n"; } 
    else { 
      sysopen(VAULT, "$path/$file", O_RDWR | O_EXCL | O_CREAT | O_BINARY) or die "couldn't create $file for R/W: $!\n"; 
    } 

    my $upfh = \*VAULT; 
    flock $upfh, 2; 
    seek $upfh, 0, 0; 
    select((select($upfh), $| = 1)[0]); 
    while(sysread($file_name, $data, 8192)) { 
      syswrite($upfh, $data, 8192) or die "couldn't write $upfh: $!\n"; 
    } 

    close $upfh; } 

Когда я использую read и print с помощью сценария загрузки FastCGI, файлы, загруженные с искаженной (в том числе простые текстовые файлы), это происходит потому, что perl использует буферизованный ввод/вывод. Но когда я использую syswrite и sysread т. Е. Небуферизованный ввод-вывод, в результате получаю хорошие текстовые файлы, но двоичные файлы все равно повреждены.

+1

Не могли бы вы рассказать, какие библиотеки вы используете? И используете ли вы строгие предупреждения и предупреждения? –

+0

использование CGI :: Быстрый qw (: стандартный); использовать строгое; использование кодировки 'utf8'; использование FCGI :: ProcManager; use File :: Basename; DBD :: SQLite; использовать Fcntl; использовать POSIX; и да, я использую предупреждения. – user199509

+0

Проблема заключалась в использовании кодировки 'utf8'. После того, как я удалю его, все файлы загружаются без коррупции. – user199509

ответ

1

Я вижу некоторую путаницу в отношении $file и $file_name. Последний либо неправильно назван, либо неправильно использован.

Кроме того, это звучит для меня как проблема binmode. Вы можете позвонить по телефону binmode на свой дескриптор ввода.

В качестве дополнительной подсказки, вы можете открыть файлы в sysopen(my $upfh, .... И поиск буферизуется, поэтому, если вы используете syswrite (я бы не стал), тогда вы можете лучше использовать sysseek.

+0

Спасибо, Я пытаюсь использовать sysseek, но мне это не помогает. и да $ file и $ file_name неправильно названы, но отлично работают. после добавления binmode (VAULT) в инструкции if-else, сразу после sysopen, изменений нет. некоторые истечения срока действия показывают мне, что текстовые файлы развращают тоже, когда они довольно большие. Я добавляю $ CGI :: POST_MAX = 1024 * 10000, но это не помогает. – user199509

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