perlunity.de - PERL | JAVASCRIPT | PHP | MySQL | APACHE



#!/COMMUNITY

Members: 5598
davon online: 1
weitere User: 1
Click for quality!



22.04.2018 / 23:57

Community-Member werden   |   Paßwort vergessen   |   OnlineMonitor (1) Wer ist online ... OnlineMonitor starten !
     

 

Home


PERLscripts


PHPscripts


JAVAscripts


Hilfreiches


Links2www


Newscenter


Community


Interna




Binäre Daten und Files

Als C-Programmierer kennt man die Funktionen, um in binären Files zu manövrieren. In Perl ist es sehr ähnlich: Für Lesen gibt es read, für Schreiben print (nein, nicht write!), für Positionieren seek und um die aktuelle Position im File zu erhalten tell. Diese Funktionen gelten auch für Textfiles, werden jedoch meistens in Files mit fester Recordlänge (fixed record length) verwenden, wo beliebiger Zugriff auf einzelne Records (random access) durch einfache Berechnungen möglich ist.

Zuerst machen wir als einfaches Beispiel die Kopie eines Files mit read und print:

   open FROM, "InFile";
   open TO, ">OutFile";
   while (read FROM, $buf, 16384) {
       print TO $buf;
   }
   close FROM;
   close TO

open und close funktionieren wie früher besprochen.

( Es gäbe auch noch eine einfachere Möglichkeit, ein File zu kopieren: Mit dem Modul File::Copy. )

binäre Daten

Nehmen wir an, wir hätten ein File, welches von einem C-Program geschrieben wurde und zwar mit fester Recordlänge, dh. mit fwrite einen struct mit bekannter Definition. Wir wollen diese Records auslesen und den Inhalt der einzelnen Felder zugreifen. Dazu verwenden wir die Funktionen read und unpack. unpack benötigt als Parameter ein Template, welches die Struktur des Records (struct) beschreibt und einen String, welcher den Record beinhaltet. Das Template ist eine Folge von Buchstaben, welche die Reihenfolge und Art der einzelnen Felder des Records beschreibt:

  • A,a ASCII String
  • b,B Bit String
  • h,H Hex String
  • c,C Signed/Unsigned Char
  • s,S Signed/Unsigned Short
  • i,I Signed/Unsigned Integer
  • l,L Signed/Unsigned Long
  • f Float
  • d Double
  • p Pointer to a null-terminated string.

Weitere Templates sind unter der Funktion pack zu finden.

Ein Teil des C-Codes für obiges Beispiel sieht wie folgt aus:

   struct{char st[4]; int in; double d;} gaga;
   fwrite(&gaga, sizeof(gaga) 1 , fp)   (* FILE *fp *)

Perl-Code:

   $template = "a4 i d";
   $len = length pack($template,'',0,0)
   read(FP,$rec,$len)     # open FP, "filename";
   ($str,$in,$d) = unpack($template,$rec);

Mit pack kann ein Record wie in C erzeugt werden. Wir brauchen diese Funktion hier, um die Länge des Records zu bestimmen.

Formatierte Ausgabe

Perl liefert einen Mechanismus um einfache Reports und Tabellen auszugeben, der über die Möglichkeiten der print- und printf-Funktion hinausgeht. Man deklariert das Layout der Ausgabe mit format und gibt die einzelnen Records mit write aus. Die Deklaration format kann irgendwo im Programm erfolgen und hat die folgende Syntax:

   format NAME =
   FORMLIST
   .

NAME ist der Formatname und wird defaultmässig dem gleichnamigen Filehandle zugeordnet. Falls er weggelassen wird, wird STDOUT angenommen.
FORMLIST besteht aus einer Folge von Zeilen, die jede entweder eine Kommentarzeile sein kann, mit einen #-Zeichen am Anfang, eine Format-Zeile, welche das Aussehen der Ausgabe beschreibt, oder eine Parameterzeile, welche die auszugebenden Variablen zu der vorangehenden Format-Zeile angibt. Mit der gleichen Syntax kann das Format für eine oder mehrere Kopfzeilen angegeben werden. Der Name von Kopfzeilen-Formaten hat die Form FILEHANDLE_TOP, resp. für STDOUT nur TOP. Es gibt wiederum eine Anzahl von Spezialvariablen, welche im Zusammenhang mit Formaten gebraucht werden können. Zum Beispiel ist $~ gleich dem Namen des aktuellen Ausgabeformates, resp. $^ derjenige, des aktuellen Kopfzeilen-Formates.

Beispiel: Wir möchten nun das binäre File, welches wir oben gelesen habe, schön formattiert ausgeben:

   format TOP =
             Binaeres File
   STRING       INTEGER        DOUBLE
   ----------------------------------
   .
   format =
   # String linksbuendig, Integer zentriert, Double rechtsbuendig
   @<<<<        @||||||        @>>>>>
   $str,$in,$d
   .
   
   while (read(FP,$rec,$len)) {
       ($str,$in,$d) = unpack($template,$rec);
       write;
   }

Für weitere Details zu Formaten, wende man sich an das Manual.

 


Uebung

Schreibe ein Programm, welches das File /var/adm/wtmp eines UNIX-Systemes ausliest. Dieses File enthält die Informationen über die Logins des Systems.   Formattiere die Ausgabe mit format. Die Struktur des Files /var/adm/wtmp ist systemabhängig. (Siehe man utmp).



zurück Inhalt weiter






-
-