我需要提供一个大文件(500+ MB),以便从Web服务器无法访问的位置下载.我发现了使用PHP提供大文件的问题,这与我的情况相同,但我使用的是Perl而不是PHP.
我尝试逐行打印文件,但这不会导致浏览器在抓取整个文件之前提示下载:
use Tie::File; open my $fh, '<', '/path/to/file.txt'; tie my @file, 'Tie::File', $fh or die 'Could not open file: $!'; my $size_in_bytes = -s $fh; print "Content-type: text/plain\n"; print "Content-Length: $size_in_bytes\n"; print "Content-Disposition: attachment; filename=file.txt\n\n"; for my $line (@file) { print $line; } untie @file; close $fh; exit;
Perl是否具有与PHP的readfile()
功能相同的功能(如PHP所示)或者有没有办法完成我在这里尝试做的事情?
如果你只想将输入粘贴到输出,这应该可以解决问题.
use Carp (); { #Lexical For FileHandle and $/ open my $fh, '<' , '/path/to/file.txt' or Carp::croak("File Open Failed"); local $/ = undef; print scalar <$fh>; close $fh or Carp::carp("File Close Failed"); }
我想在回应"Perl是否有PHP ReadFile Equivelant"时,我想我的答案是"但它并不真的需要一个".
我已经使用过PHP的手动文件IO控件而且它们很痛苦,相比之下,Perls只是如此易于使用,因为一个适合所有人的功能似乎过度杀戮.
此外,您可能希望查看X-SendFile
支持,并基本上向您的网络服务器发送一个标题,告诉它要发送的文件:http://john.guen.in/past/2007/4/17/send_files_faster_with_xsendfile/ (当然假设它具有足以访问该文件的权限,但该文件通常不能通过标准URI访问)
编辑注意到,这是更好地做一个循环,我测试了一个硬盘驱动器上面的代码,它并含蓄地尝试存储在一个看不见的临时变量整个事情,吃所有您的RAM.
以下改进的代码以8192个字符块的形式读取给定文件,这样可以提高内存效率,并且可以获得与我的磁盘原始读取速率相当的吞吐量.(我还指出它/ dev/full适合和咯咯笑,并且获得了500mb/s的健康吞吐量,并且它没有吃掉我所有的公羊,所以一定要好)
{ open my $fh , '<', '/dev/sda' ; local $/ = \8192; # this tells IO to use 8192 char chunks. print $_ while defined ( $_ = scalar <$fh> ); close $fh; }
{ open my $fh , '<', '/dev/sda5' ; print $_ while ( sysread $fh, $_ , 8192 ); close $fh; }
这实际上使性能提高了一倍......在某些情况下,我获得了比DD更好的吞吐量O_o.