我使用以下perl代码从SEC网站下载10-K。但是,我得到了"不记忆的!"当脚本显然被卡住处理特别大的10K文件时,每百个文件都会发出消息。我如何避免这种"不记忆力"的任何想法!大文件的错误?
#!/usr/bin/perl
use strict;
use warnings;
use LWP;
my $ua = LWP::UserAgent->new;
open LOG , ">download_log.txt" or die $!;
######## make sure the file with the ids/urls is in the
######## same folder as the perl script
open DLIST, "downloadlist.txt" or die $!;
my @file = <DLIST>;
foreach my $line (@file) {
#next if 0.999 > rand ;
#print "Now processing file: $linen" ;
my ($nr, $get_file) = split /,/, $line;
chomp $get_file;
$get_file = "http://www.sec.gov/Archives/" . $get_file;
if ($get_file =~ m/([0-9|-]+).txt/ ) {
my $filename = $nr . ".txt";
open OUT, ">$filename" or die $!;
print "file $nr n";
my $response =$ua->get($get_file);
if ($response->is_success) {
print OUT $response->content;
close OUT;
} else {
print LOG "Error in $filename - $nr n" ;
}
}
}
只需让LWP
直接将响应数据存储到文件中,而不是在HTTP::Response
对象中。以这种方式进行编码也更简单
这是一个示例程序。我目前无法测试它,但它确实编译了
我最近注意到很多人在处理数据之前将编写代码读为内存中的整个文件,我不明白为什么它如此受欢迎。它浪费了记忆,通常很难以这种方式编码解决方案。我更改了您的程序以在下载列表文件的一次读取一行并直接使用它,而不是将其存储到数组
中use strict;
use warnings 'all';
use LWP;
my $ua = LWP::UserAgent->new;
open my $dl_fh, '<', 'downloadlist.txt' or die "Can't open download list file: $!";
open my $log_fh, '>', 'download_log.txt' or die "Can't open log file: $!";
STDOUT->autoflush;
while ( <$dl_fh> ) {
# next if 0.999 > rand;
# print "Now fetching file: $_";
chomp;
my ($num, $dl_file) = split /,/;
unless ( $dl_file =~ /[0-9|-]+.txt/ ) {
print $log_fh qq{Skipping invalid file "$dl_file"n};
next;
}
my $url = "http://www.sec.gov/Archives/$dl_file";
my $filename = "$num.txt";
print qq{Fetching file $filenamen};
my $resp = $ua->get($url, ':content_file' => $filename);
printf $log_fh qq{Download of "%s" %sn},
$filename,
$resp->is_success ?
'successful' :
'FAILED: ' . $resp->status_line;
}
我最近使用线程和数千个LWP请求遇到了类似的问题。从来没有弄清楚内存泄漏是什么,但是切换到http :: tiny解决了它。
从LWP到HTTP :: Tiny很简单:
use HTTP::Tiny;
my $ua = HTTP::Tiny->new;
my $response =$ua->get($get_file);
if ($response->{success}) {
print OUT $response->{content};
...当然HTTP::Tiny
可以为您提供保存部分,例如LWP
。
您也可以尝试在循环内制作一个新的LWP
对象,希望能够开始垃圾收集,但也对我不起作用。LWP
怪物内部有一些泄漏的东西。
编辑:尝试将2GB文件下载到字符串中也可能存在问题,镜像方法应该为您解决。