Toon posts:

[PERL] open file probleem

Pagina: 1
Acties:

Verwijderd

Topicstarter
Als ik via onderstaande code een gif file op de server open en verstuur wordt niet de gehele file verstuurd maar het eerste gedeelte van de file.


Perl:
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
open(FILE,"******.gif") || warn $!;
         
         $content=<FILE>;
         close(FILE);

         $content= encode_base64($content);  ##  Use base64 for encoding the contents


sub encode_base64 ($;$){
    my $res = "";
    my $eol = $_[1];
    $eol = "\n" unless defined $eol;
    pos($_[0]) = 0;                          # ensure start at the beginning
    while ($_[0] =~ /(.{1,45})/gs) {
         $res .= substr(pack('u', $1), 1);
         chop($res);
    }
    $res =~ tr|` -_|AA-Za-z0-9+/|;               # `# help emacs
    # fix padding at the end
    my $padding = (3 - length($_[0]) % 3) % 3;
    $res =~ s/.{$padding}$/'=' x $padding/e if $padding;
    # break encoded string into lines of no more than 76 characters each
    if (length $eol) {
         $res =~ s/(.{1,76})/$1$eol/g;
    }
    $res;
}

Verwijderd

Topicstarter
De oplossing
Perl:
1
2
3
4
5
6
7
8
my $nl;
    $nl=$/;

         undef $/;
         open(FILE,"<","*****.gif") || warn $!;
         $content = <FILE>;
         close(FILE);
         $/=$nl;

  • muba
  • Registratie: April 2002
  • Laatst online: 19-10-2013

muba

Prince of Persia!

mja, want als je gewoon doet $content = <FILE>;, dan wordt alles tot en met de eerste $/ (line seperator) gelezen, dus als er ergens in de .gif een "\n" (newline, standaardwaarde van $/) staat, dan wordt de .gif tot daar gelezen. Undef $/ en het hele bestand wordt in 1 hap gelezen :)

Reporter: Mister Gandhi, what do you think of western civilisation?
Gandhi: I think it would be a good idea


  • muba
  • Registratie: April 2002
  • Laatst online: 19-10-2013

muba

Prince of Persia!

Pas echter wel op dat je hiermee je geheugen aanzienlijk hard kan laten vollopen, zeker als er redelijk veel grote gifjes tegelijk opgevraagd worden. Beter is het misschien om met while ($content = <FILE>) het bestand toch 'regel voor regel' (van newline tot newline dus) in te lezen. Denk ik.

Reporter: Mister Gandhi, what do you think of western civilisation?
Gandhi: I think it would be a good idea


  • tomato
  • Registratie: November 1999
  • Niet online
Als het om grote bestanden gaat is het wellicht beter om sysread te gebruiken. Om in binary mode te lezen moet je dat op Windows systemen nog expliciet aangeven, het is sowieso wel verstandig om je code portable te houden:
code:
1
2
3
4
5
6
7
8
9
open(H, '< file') or die 'Foutje';
binmode(H);

my $buf;
while(sysread(H, $buf, 1024)) {
   print $buf;
}

close(H);

  • muba
  • Registratie: April 2002
  • Laatst online: 19-10-2013

muba

Prince of Persia!

wat doet sysread dan pcies? Die leest een op te geven hoeveelheid bytes (en in jouw voorbeeld dus 1 KB) uit het bestand ofzo? En ik neem aan dat als het bestand uit 1028 bytes bestaat, er dus 2 blokken ontstaan (1024 + 4)?

Reporter: Mister Gandhi, what do you think of western civilisation?
Gandhi: I think it would be a good idea


  • tomato
  • Registratie: November 1999
  • Niet online
MUBA schreef op 05 June 2003 @ 19:08:
wat doet sysread dan pcies? Die leest een op te geven hoeveelheid bytes (en in jouw voorbeeld dus 1 KB) uit het bestand ofzo? En ik neem aan dat als het bestand uit 1028 bytes bestaat, er dus 2 blokken ontstaan (1024 + 4)?
Precies, sysread gebruikt de read system call en 1024 bytes tegelijk gaat een stuk sneller dan regel voor regel bij iets grotere bestanden.

Verwijderd

Topicstarter
Om in binary mode te lezen moet je dat op Windows systemen nog expliciet aangeven, het is sowieso wel verstandig om je code portable te houden:
Het portable houden van code sluit dus ook het gebruik van bepaalde modules uit en hoe zou je dit dan oplossen met de paden van de verschillende systemen voor het openen van files?

Is het in mijn geval wel zinnig om sysread te gebruiken, de gifjes worden toch gelijk verstuurd met sendmail.

  • muba
  • Registratie: April 2002
  • Laatst online: 19-10-2013

muba

Prince of Persia!

uhm, in Perl heb je de hele leuke mogenlijkheid om directory seperators zo ("\\" (dubbel, want je moet er natuurlijk 1 escapen)) of zo ("/") te schrijven. IIG wel in de Windows-versie, dus ik neem aan dat je in *n?x ook wel kan kiezen. Persoonlijk kies ik dan altijd de "/"-variant, omdat "\\" A) minder mooi staat en B) het mij een beetje verwart met een Windows-netwerkpad (\\computernaam\shared_source)

Reporter: Mister Gandhi, what do you think of western civilisation?
Gandhi: I think it would be a good idea


  • tomato
  • Registratie: November 1999
  • Niet online
Verwijderd schreef op 05 June 2003 @ 20:13:
Is het in mijn geval wel zinnig om sysread te gebruiken, de gifjes worden toch gelijk verstuurd met sendmail.
Als je alles uiteindelijk toch in een scalar wilt proppen maakt het inderdaad niet uit.
Pagina: 1