【发布时间】:2015-04-04 11:00:05
【问题描述】:
我在最新版本的 Strawberry Perl for Windows 下的以下代码存在问题:我想读入目录中的所有文本文件并处理它们的内容。我目前看不到逐行处理它们的方法,因为我想对文件内容进行的一些更改跨越换行符。处理主要涉及删除大块文件(在下面的示例代码中,它只是一行,但理想情况下我会运行几个类似的正则表达式,每个都从文件中删除内容)
我在大量文件 (>10,000) 上运行此脚本,但它总是以“内存不足!”而崩溃。大于 400 MB 的特定文件上的消息。问题是,当我编写一个只处理一个文件的程序时,代码可以正常工作。
这台机器有 8 GB RAM,所以我认为物理 RAM 不是问题。
我阅读了有关记忆问题的其他帖子,但没有找到任何可以帮助我实现目标的内容。
谁能建议我需要更改哪些内容才能使程序正常运行,即提高内存效率或以某种方式回避问题?
use strict;
use warnings;
use Path::Iterator::Rule;
use utf8;
use open ':std', ':encoding(utf-8)';
my $doc_rule = Path::Iterator::Rule->new;
$doc_rule->name('*.txt'); # only process text files
$doc_rule->max_depth(3); # don't recurse deeper than 3 levels
my $doc_it = $doc_rule->iter("C:\Temp\");
while ( my $file = $doc_it->() ) { # go through all documents found
print "Stripping $file\n";
# read in file
open (FH, "<", $file) or die "Can't open $file for read: $!";
my @lines;
while (<FH>) { push (@lines, $_) }; # slurp entire file
close FH or die "Cannot close $file: $!";
my $lines = join("", @lines); # put entire file into one string
$lines =~ s/<DOCUMENT>\n<TYPE>EX-.*?\n<\/DOCUMENT>//gs; #perform the processing
# write out file
open (FH, ">", $file) or die "Can't open $file for write: $!";
print FH $lines; # dump entire file
close FH or die "Cannot close $file: $!";
}
【问题讨论】:
-
不确定您是否遇到过这个问题,但这是堆内存分析和使用内存映射文件而不是使用文件的一个很好的答案。 stackoverflow.com/questions/9733146/…
-
而不是进行多行搜索和替换,为什么不只是:1)逐行读取文件,直到到达起始分隔符 2)检查后续行是否符合您想要的条件;如果是这样,请不要在输出文件中打印任何内容,直到到达结束分隔符;如果没有,请打印出来。
-
你可以试试File::Sip
-
看起来你正在处理 XML 数据,你应该使用
XML::Twig -
这不是一个解决方案(这就是我将其作为评论发布的原因),但是,对于它的价值,您可以以
my @lines = <FH>;的形式一次性读取文件
标签: windows string perl memory