Thread Kommaseparierte Listen bereichsweise ausgeben. (28 answers)
Opened by Gast at 2006-04-14 16:54

sid burn
 2006-04-15 07:14
#64968 #64968
User since
2006-03-29
1520 Artikel
BenutzerIn

user image
Quote
mehrere Antwortende sagten hier, dass ich das Filehandle sofort, also noch for dem while() schliessen soll. Wie soll dann aber daraus gelesen werden, wenn es geschlossen ist? Ich habe es natürlich ausprobiert und tatsächlich, wenn ich for dem while() das Filehandle close, bekome ich aber folgendes:

Du sollst das Filehandle nur dann sofort schließen, wenn du den Inhalt der Datei in einem Array eingelesen hast. Also folgendes gemacht hast.

Code: (dl )
1
2
3
4
5
6
7
8
open FILE, "<", "datei.txt";
@file = <FILE>;
close FILE;

for (@file)
{
print;
}

Da die Datei komplett im Array liegt, also im Speicher, kannst du das Filehandle sofort schließen. Wenn du das Filehandle danach natürlich noch benutzt, also z.B. in deiner while Schleife dann geht das natürlich nicht.

Allerdings macht es ja wenig Sinn das Filehandle zu benutzen wenn die Datei im Array liegt. Wenn man das Filehandle weiterhin benutzen würde, dann wäre das einlesen im Array reine Zeit- und Speicherverschwendung gewesen.

Zum anderen würde das auch nicht ohne weiteres gehen. Da du nämlich die komplette Datei in das Arrays eingelesen hast, zeigt das dateihandle auf EOF. Wenn du danach noch <FILE> aufrufst, würde nichts zurück geliefert werden. Also ein FALSE Wert.

Du müsstest die Position erstmal wieder mit "seek" auf den Anfang der Datei setzen damit du nach dem Einlesen des Arrays das Filehandle benutzen kannst. Aber die ganze Aktion wäre ja total Sinnlos.

Quote
Sieht also aus und ist für mich logisch, dass man doch erst nach der Operation close'n kann, oder galt das für den Fall, wenn man ein Array gefüllt hat ( also FH öffnen, @liste füllen, FH closen, while(@liste)), dann muss ich aber wieder mit $_=shift(@liste) innerhalb von while() arbeiten und das wurde ja von Euch auch abgeraten, weil man besser mit dem Filehandler arbeiten soll... hmm... ? :confused:

Nein, du itterierst dann über das Array mit einer foreach Schleife so wie oben angegeben. Hier einmal etwas ausführlicher. Deine Möglichkeit geht natürlich auch, würde ich aber nicht machen. Und dein Befehl würde ich als while Bedingung dann benutzen, und nicht innerhalb des while Blockes. Aber ein foreach ist hier schöner und besser lesbarer.

Code: (dl )
1
2
3
4
foreach $i (@file)
{
print $i;
}

Würde dann ebenfalls die komplette Zahl ausgeben. Wenn du das Skalar weg lässt, dann wird die Defaultvariable $_ gefüllt. Und das "each" kannst du auch weg lassen.

Quote
sid burn erwähnte aber, dass dieses "auf einmal in ein Array Einlesen", bei grösseren Dateien nicht gut wäre. Es leuchtet mir ein, dass wie Du sagtest, mit meiner Variante "der globale Namensraum mit einem Filehandle verschmutzt wird", allerdings scheint mir das Argument das Problems mit dem "auf einmal Einlesen in ein Array" grösser, als der Vorteil des Sauberhaltens des globalen Namensraums, oder habe ich es hier wieder falsch verstanden?

Bei größeren Skripten machen die Klammern schon einen Unterschied. Bei so einen kleinen Skript würde ich dafür nicht extra einen neuen Namensraum benutzen. Also keine Klammern machen.

Du kannst aber auch beides Benutzen. Soweit Klammern wie es nötig ist, und natürlich eine Datei nicht komplett im Speicher einlesen.\n\n

<!--EDIT|sid burn|1145071806-->
Nicht mehr aktiv. Bei Kontakt: ICQ: 404181669 E-Mail: perl@david-raab.de

View full thread Kommaseparierte Listen bereichsweise ausgeben.