Perl-Programmierung: Dateien

Aus Wikibooks



Dateitest-Operatoren[Bearbeiten]

Ein Dateizugriff ist ein sehr systemnaher Vorgang. Zugriffe auf nichtexistente Dateien können zu Abstürzen unseres Programms führen. Um das zu vermeiden muß unser Perl-Programm sich häufig zur Laufzeit, vor dem eigentlichen Dateizugriff, informieren, was genau auf dem Dateisystem los ist. Dazu muß der Programmierer seinem Programm die richtigen Fragen an die Hand geben.

Perl stellt eine ganze Reihe von Operatoren zur Verfügung um Dateien zu testen. Diese sogenannten Dateitest-Operatoren ( auch -X-Operatoren genannt ) ermöglichen es dem Programmierer, zu überprüfen wie der Zustand einer Datei ist. Hier eine komplette Liste der vorhandenen Operatoren:

-r   Datei / Verzeichnis ist für effektiven Benutzer oder Gruppe lesbar
-w   Datei / Verzeichnis ist für effektiven Benutzer oder Gruppe schreibbar
-x   Datei / Verzeichnis ist für effektiven Benutzer oder Gruppe ausführbar
-o   Datei / Verzeichnis gehört effektivem Benutzer
-R   Datei / Verzeichnis ist für tatsächlichen Benutzer oder Gruppe lesbar
-W   Datei / Verzeichnis ist für tatsächlichen Benutzer oder Gruppe schreibbar
-X   Datei / Verzeichnis ist für tatsächlichen Benutzer oder Gruppe ausführbar
-O   Datei / Verzeichnis gehört tatsächlichem Benutzer
-e   Datei / Verzeichnis existiert
-z   Datei existiert und hat die Größe null ( für Verzeichnisse immer unwahr )
-s   Datei existiert und hat eine andere Größe als null ( Wert ist Größe in Bytes )
-f   Angabe ist eine "einfache" Datei
-d   Angabe ist ein Verzeichnis
-l   Angabe ist ein symbolischer Link
-S   Angabe ist ein Socket
-p   Angabe ist eine benannte Pipe ( fifo )
-b   Angabe ist eine spezielle Blockdatei
-c   Angabe ist eine zeichenorientierte Datei
-u   Datei / Verzeichnis ist setuid
-g   Datei / Verzeichnis ist setgid
-k   Datei / Verzeichnis hat das "Sticky Bit" gesetzt
-t   Dateihandle ist ein TTY
-T   Datei sieht aus wie eine Text-Datei
-B   Datei sieht aus wie eine Binär-Datei
-M   "Alter" der Datei ( in Tagen )
-A   Zeit des letzten ( in Tagen )
-C   Letzte Änderung des Inode ( in Tagen )

Hier ein Beispiel um die Funktion dieser Operatoren zu erläutern:

#!/usr/bin/perl
use strict;
use warnings;
# überprüfen ob Datei existiert

my $datei = '/tmp/testfile';
if ( -e $datei ) {
    print "Datei existiert\n";
}

Dateien öffnen und schließen[Bearbeiten]

Um eine Datei zu öffnen benutzt man in Perl die open-Funktion, zum Schließen die close-Funktion.


#!/usr/bin/perl
use strict;
use warnings;
# Datei überprüfen und öffnen

my $datei = '/tmp/testfile';
if ( -e $datei ) {
    print "Datei $datei existiert\n";
    open (my $fh, "<", $datei) or die "Kann Datei $datei nicht oeffnen: $!";
    close $fh;
} 
else {
  print "Datei $datei existiert nicht\n";
}

In diesem Beispiel wird zuerst überprüft, ob die Datei existiert. Nachdem dieser Test erfolgreich ist, wird die entsprechende Meldung ausgegeben und direkt im Anschluss die Datei geöffnet (standardmäßig im Read-Modus). Würde das fehlschlagen, würde das Programm mit entsprechender Fehlermeldung versterben (die). Zuletzt wird das File wieder geschlossen.

Modi für Dateihandles[Bearbeiten]

Im obigen Beispiel wurde eine Datei standardmäßig im Lesemodus geöffnet. Was ist jedoch, wenn wir eine Datei schreibend öffnen wollen ( zB um ein Logfile zu schreiben )? Für diese Aufgabe gibt es die sogenannten Modi mit denen eine Datei geöffnet werden kann. Aus historischen Gründen kann die Funktion open mit zwei oder mit drei Argumenten benutzt werden. Beim Aufruf mit zwei Argumenten wird der Modus dem Dateinamen vorangestellt. Allgemein empfohlen ist jedoch die modernere Art des Aufrufes mit drei Argumenten.

Hier die Übersicht über die Modi:

<   Pfad     Zugriff nur lesend
>   Pfad     Zugriff nur schreibend ( neu anlegen / bestehende Datei überschreiben )
>>  Pfad     Zugriff nur schreibend ( neu anlegen / an bestehende Datei anhängen )
+<  Pfad     Lese-/Schreibzugriff
+>  Pfad     Lese-/Schreibzugriff ( neu anlegen / bestehende Datei überschreiben )
+>> Pfad     Lese-/Schreibzugriff ( neu anlegen / an bestehende Datei anhängen )
| Befehl     Schreibhandle an Befehl
Befehl |     Lesehandle von Befehl

Somit könnte man das obige Beispiel auch wie folgt schreiben:

#!/usr/bin/perl
use strict;
use warnings;
# Datei überprüfen und öffnen

my $datei = '/tmp/testfile';
if ( -e $datei ) {
    print "Datei $datei existiert\n";
    open (my $fh, '<', $datei) or die "Kann Datei $datei nicht zum Lesen oeffnen: $!";
    close $fh;
}

Dateien schreiben[Bearbeiten]

Jetzt, wo wir wissen, wie man eine Datei entweder lesend oder schreibend öffnet, wollen wir natürlich auch etwas mit diesen Dateien anstellen. Im nächsten Beispiel schreiben wir eine Zeile in eine neue Datei:

#!/usr/bin/perl
use strict;
use warnings;
# in Datei schreiben

my $datei = '/tmp/testfile';
if ( -e $datei ) {                                                   # Wenn Datei existiert, tun wir garnichts
    print "Datei $datei existiert\n";
}
else {                                                               # Wenn Datei nicht existiert, öffnen, bzw. anlegen.
    open (my $fh, '>', $datei) or die "Kann Datei $datei nicht zum Schreiben oeffnen: $!\n";
    print $fh "Eine tolle Zeile voller toller Zeichen!\n";           # hier schreiben wir rein
    close $fh;
}

Wie man sieht, ist das Schreiben in eine Datei kinderleicht. Man kann der print-Funktion das Dateihandle übergeben und es einfach hineinschreiben lassen. Achtung: Kein Beistrich!

Dateien auslesen[Bearbeiten]

Einfach nur eine Datei zu schreiben scheint aber auch langweilig. Also wollen wir im nächsten Schritt eine Zeile aus einer Datei einlesen.

#!/usr/bin/perl
use strict;
use warnings;
# eine Zeile auslesen

my $datei = '/tmp/testfile';
if ( -e $datei ) {
    print "Datei $datei existiert\n";
    
    open (my $fh, '<',  $datei) or die "Fehler beim Oeffnen zum Lesen: $!";
    my $line = <$fh>;
    print $line;
    close $fh;
}

Dieses Beispiel gibt die erste Zeile von /tmp/testfile zurück. Nun ist das zwar nett, aber eventuell unzureichend für unseren Geschmack, also lesen wir im nächsten Beispiel die komplette Datei aus.

#!/usr/bin/perl
use strict;
use warnings;
# Datei auslesen

my $datei = '/tmp/testfile';
if ( -e $datei ) {
    print "Datei $datei existiert\n";
    
    open (my $fh, '<', $datei) or die "Fehler beim Oeffnen: $!";
    while (<$fh>) {
        print $_;
    }
    close $fh;
}

Das gibt die gesamte Datei aus.