Schrift
[thread]949[/thread]

perl upload script: Speicherauslastung

Leser: 1


<< >> 6 Einträge, 1 Seite
Gast Gast
 2007-06-29 13:54
#228 #228
Hallo,

zum upload grosser Video Dateien und wegen einer Verlaufanzeige habe ich mich in perl eingearbeitet. Generell funktioniert das auch, wenn die zu uploadenden Dateien nicht grösser als das hardlimit an Speicherverbrauch für Perl Scripte liegen. Eigentlich klar könnte man denken. Ziel ist es, dass das Perl script möglichst wenig Speicher verbraucht. Der upload an sich erfüllt diese Bedingung. Hier wird das STDIN (post raw data) mit einer while Schleife in 4 kb grossen Stücken in eine Datei gestreamt. Somit habe ich z.B. eine 700 MB grosse Datei hochgeladen, obwohl das hard limit bei 200 MB liegt. Die Datei wird ja nicht komplett angefasst.

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
open(FH,">","$post_data_file");

$ofh = select(FH); $| = 1; select ($ofh);

while (read (STDIN ,$LINE, 4096) && $b_read < $len )
{
if (-e "$exit_file") { unlink ("$exit_file"); exit;}

$b_read += length $LINE;

select(undef, undef, undef,0.01);

print FH $LINE;
}


Jetzt zum eigentlichen Problem. Ich habe die post raw data als Datei auf dem Server abgelegt. Nun ist der nächste Schritt die eigentlich upgeloadete Datei in der post raw data Datei wieder zufinden. Genau hier ist das Problem. Das perl script muss scheinbar die gesamte Datei in den Arbeitsspeicher laden um die Elemente anzusprechen.

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
close(STDIN);
open(STDIN,"$post_data_file") or &_bye("Upload fehlgeschlagen");

my $cgi = new CGI();
my $assign = "";
my %vars = $cgi->Vars;

while(($key,$value) = each %vars)
{
if(defined $value && $value ne '')
{
my $fh = $cgi->upload($key);

binmode ($fh);

if(defined $fh)
{
...


Gibt es vielleicht eine Möglichkeit die upgelodete Datei speicherschonend aus der post raw data zu ziehen?

edit pq: code-tags hinzugefügt\n\n

<!--EDIT|pq|1183124349-->
pq
 2007-06-29 17:51
#229 #229
User since
2003-08-04
12208 Artikel
Admin1
[Homepage]
user image
versuch mal:
my $cgi = CGI->new(\&hook);
perldoc CGI
hab aber selbst noch nicht ausprobiert, ob dann die datei auch komplett in den
speicher geladen wird oder nicht. ich wuerde aber mal vermuten, nein.
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. -- Damian Conway in "Perl Best Practices"
lesen: Wiki:Wie frage ich & perlintro Wiki:brian's Leitfaden für jedes Perl-Problem
bloonix
 2007-06-29 18:10
#230 #230
User since
2005-12-17
1615 Artikel
HausmeisterIn
[Homepage]
user image
[quote=Guest,29.06.2007, 11:54]
Code: (dl )
while (read (STDIN ,$LINE, 4096) && $b_read < $len ){
[/quote]
Das klappt? hmm da bin ich mir nicht so sicher. Angenommen die Länge,
die über STDIN reinkommen soll ist 4097 Bytes. Der erste Schleifendurch-
lauf klappt, da 4096 Bytes geliefert werden, der zweite/letzte hängt aber
solange, da nur noch 1 Byte übrig ist, read() verlangt aber 4096 :)

perl -e 'print length while read STDIN, $_, 100'

Erst nach 100 Bytes (100 Zeichen) wird die Länge ausgegeben.
What is a good module? That's hard to say.
What is good code? That's also hard to say.
One man's Thing of Beauty is another's man's Evil Hack.
bloonix
 2007-06-29 18:27
#231 #231
User since
2005-12-17
1615 Artikel
HausmeisterIn
[Homepage]
user image
... sorry, ich vergaß... ausserdem sollte man prüfen, ob auch tatsächlich
soviel gelesen wurde wie erwartet like

while (4096 == read (STDIN ,$LINE, 4096) ...
What is a good module? That's hard to say.
What is good code? That's also hard to say.
One man's Thing of Beauty is another's man's Evil Hack.
pq
 2007-06-29 18:30
#232 #232
User since
2003-08-04
12208 Artikel
Admin1
[Homepage]
user image
[quote=opi,29.06.2007, 16:10]perl -e 'print length while read STDIN, $_, 100'

Erst nach 100 Bytes (100 Zeichen) wird die Länge ausgegeben.[/quote]
Code: (dl )
1
2
3
4
5
6
7
8
9
10
$ echo "123456789012" | perl -wle'
my $data;
while (read(STDIN, $data, 5)) {
print "chunk: <$data>";
}'
chunk: <12345>
chunk: <67890>
chunk: <12
>
$

read() liest ja nur bis zum eof.
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. -- Damian Conway in "Perl Best Practices"
lesen: Wiki:Wie frage ich & perlintro Wiki:brian's Leitfaden für jedes Perl-Problem
bloonix
 2007-06-29 18:43
#233 #233
User since
2005-12-17
1615 Artikel
HausmeisterIn
[Homepage]
user image
@pq, you are right! somit erledigt sich auch die prüfung, das man testen soll, wieviel man gelesen hat.
What is a good module? That's hard to say.
What is good code? That's also hard to say.
One man's Thing of Beauty is another's man's Evil Hack.
<< >> 6 Einträge, 1 Seite



View all threads created 2007-06-29 13:54.