通过HTTP提供非常大的二进制文件时内存不足

Den*_*HER -1 perl cgi http file out-of-memory

下面的代码是我们正在使用的Perl CGI脚本的原始代码.即使对于非常大的文件,它似乎也在起作用,但对于非常大的文件却不行.

目前的代码是:

$files_location = $c->{target_dir}.'/'.$ID;
open(DLFILE, "<$files_location") || Error('open', 'file');
@fileholder = <DLFILE>;
close (DLFILE) || Error ('close', 'file');

print "Content-Type:application/x-download\n";
print "Content-Disposition:attachment;filename=$name\n\n";
print @fileholder;
binmode $DLFILE;
Run Code Online (Sandbox Code Playgroud)

如果我正确理解代码,它会在"打印"它之前将整个文件加载到内存中.当然我觉得加载和显示它会更好吗?但在阅读了许多论坛和教程之后,我仍然不确定如何做到最好,使用标准的Perl库...

最后一个问题,为什么最后指定"binmode"?

非常感谢任何提示或建议,

Bor*_*din 5

我不知道binmode $DLFILE是为了什么.$DLFILE与文件句柄无关,现在DLFILE设置文件的binmode已经读到最后有点迟了.这可能只是一个错误

你可以改用它.它使用现代Perl最佳实践,并以8K块的形式读取和发送文件

文件名似乎是由于$ID我不确定这$name是否正确,但我不知道

确保保留大括号,因为该块使Perl恢复旧值$/并关闭打开的文件句柄

my $files_location = "$c->{target_dir}/$ID";

{
    print "Content-Type: application/x-download\n";
    print "Content-Disposition: attachment; filename=$name\n\n";

    open my $fh, '<:raw', $files_location or Error('open', "file $files_location");
    local $/ = \( 8 * 1024 );

    print while <$fh>;
}
Run Code Online (Sandbox Code Playgroud)

  • 答案是肯定的,任何在这里寻找这种解决方案的人(例如初学者)*都不会*理解`local $/= \(8*1024);`(特别是`\(`part).简短的解释会很好.(只是恕我直言). (3认同)