Thread Perl Speicherprobleme mit großen Dateien (W32 Version) (31 answers)
Opened by Mapache at 2009-05-05 14:38

Gast Mapache
 2009-05-05 14:38
#121203 #121203
Ich habe ein Perl Programm geschrieben, welches mir aus einer 3,5GB Datei bestimmte Logzeilen extrahieren soll. Die Datei wird dazu zeilenweise eingelesen und an Hand von Regulären Ausdrücken untersucht.
Die resultierenden Dateien werden bis maximal 800MB groß.

Trotzdem, dass ich die große INPUT-Datei von 3,5GB zeilenweise und nicht in ein @Array einlese, bleibt mir Perl unter Windows (Activestate und Cygwin) bei etwa 1,6GB (=mein freier RAM; habe 2GB und 400 werden verbraucht) stehen.

Wieso ist das so?
Ich lese die Datei doch nicht in den Speicher ein..

Auch andere Tools kommen damit nicht klar.
Ich habe noch folgende getestet:
- Gnu AWK für Win32
- Gnu egrep für Win32
- Windows' natives "Findstr" (grep ähnlich)
- sogar das GNU Tool "split" für Win32 kommt damit nicht klar (Es splittet die Files bis zur RAM Größe (z.B. 3x500MB und macht dann ein großes File mit dem Rest))

Alle brechen irgendwann ab. Dabei lese ich doch nur Zeile für Zeile.

Hier mein Perl-Code.
Vielleicht hat ja jemand eine Idee.

Vorab:
Ich habe auch Tie::File getestet. Das liest aber sehr lange und bricht dann vor der Schleife bereits ab, als ob es das File von meiner Platte entgegen der Angabe auf der CPAN-Seite doch komplett einlesen würde.
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#!/usr/bin/perl -w

use Config;
use FileHandle;

my $sidewinderlog = shift;
my $destfolder = 'L:\\sw-logs';

my $ftp_file = "$destfolder\\ftp.log";
my $dns_file = "$destfolder\\dns.log";
my $web_file = "$destfolder\\web.log";
my $mail_file = "$destfolder\\mail.log";
my $other_file = "$destfolder\\other.log";

my $inputfh = new FileHandle "< $sidewinderlog";
my $ftp = new FileHandle "> $ftp_file";
my $dns = new FileHandle "> $dns_file";
my $web = new FileHandle "> $web_file";
my $mail = new FileHandle "> $mail_file";
my $other = new FileHandle "> $other_file";

my $c; # Count

while ( <$inputfh> ) {

$c++;
if ( ! ( $c % 10000 ) ) {
print "$c done...\n";
}
# Filter double lines
if ( ! /date=\"/ ) { next; }
# FTP
if ( /dstport: 21 / || /dstport: 20 / || /srcport: 21 / || /srcport: 20 / ||
/dstport=21,/ || /dstport=20,/ || /srcport=21,/ || /srcport=20,/
)
{
print $ftp $_;
next;
}
# DNS
if ( /dstport: 53 / || /srcport: 53 / || /dstport=53,/ || /srcport=53,/ ) {
print $dns $_;
next;
}
# WEB
if (
(/srcip: 10.10.10.1[0-9]?/ && ( /dstport: 80 / || /dstport: 53 / || /dstport: 443 / ))
||
(/srcip=10.10.10.1[0-9]?,/ && ( /dstport=80,/ || /dstport=53,/ || /dstport=443,/ ))
) {
print $web $_;
next;
}
# MAIL
if ( /dstport: 25 / || /srcport: 25 / || /dstport=25,/ || /srcport=25,/ ) {
print $mail $_;
next;
}
print $other $_;

}

close $inputfh;

close $ftp;
close $dns;
close $web;
close $mail;
close $other;


Info: Ist eine 3,5 GB Datei mit ASCII Inhalt auf einem NTFS Volume

View full thread Perl Speicherprobleme mit großen Dateien (W32 Version)