Öffnen / Schreiben mit +>datei.dat
Frank
- perl
Hallo Welt,
ich habe mal ne Frage zu
< http://de.selfhtml.org/perl/funktionen/einausgabe.htm#open>
Dort steht:
+>datei.dat bedeutet: Datei datei.dat zum Lesen und zum Schreiben von Daten öffnen.
Wenn die Datei bereits existiert, wird ihr bisheriger Inhalt überschrieben.
Wenn die Datei noch nicht existiert, wird sie automatisch angelegt.
Ich kriege den bisherigen Inhalt aber nicht ausgelesen,
sondern da steht immer nur das zugefügte "Irgendwas" drin :o(
open(LOG,"+>$dat") || &fehler("Kann <b>$dat</b> nicht lesen.");
flock(LOG, 2) || &fehler("Kein Schreib-Lock auf <b>$dat</b>.");
$data = <LOG>;
chomp($data);
$data .= "Irgendwas";
print LOG "$data";
flock(LOG, 8);
close(LOG);
Ws mache ich falsch ?
Oder ist es sowieso besser,
Öffnen->Lesen->Schliessen und dann neu Öffnen->Schreiben->Schliessen ?
Danke, Frank
hi,
ich habe mal ne Frage zu
http://de.selfhtml.org/perl/funktionen/einausgabe.htm#openDort steht:
+>datei.dat bedeutet: Datei datei.dat zum Lesen und zum Schreiben von Daten öffnen.
Wenn die Datei bereits existiert, wird ihr bisheriger Inhalt überschrieben.
Wenn die Datei noch nicht existiert, wird sie automatisch angelegt.Ich kriege den bisherigen Inhalt aber nicht ausgelesen,
Ja eben. Mit +> wird sie überschrieben.
Ws mache ich falsch ?
hier aufgepasst beim Lesen einer Datei:
$data = <LOG>;
<LOG> ist ein Filehandle. Entweder zeilenweise durch die Datei gehen mit
while(my $line = <LOG>){
chomp $line;
# usw...
}
oder den Handle auf ein Array schieben
my @file = <LOG>;
--roro
--
Das Ende der Thüringer Bratwurst:
http://rolfrost.de/cgi-bin/blog.cgi?list=1156876510
while(my $line = <LOG>){
chomp $line;
# usw...
}
Hi Bratwurst,
Danke, aber klappt nicht.
Krieg es nicht eingelesen.
Es steht was drin, aber
while(my $line = <LOG>){
print "XXX $line<br>\n";
}
bringt mir nicht eine Zeile auf den Screen.
Das Array hab ich auch versucht
ohne was auslesen zu können :o(
Noch ne Idee vielleicht ?
Im Endeffekt solls auch nur ein schneller Counter werden.
Lesen -> 1 draufaddieren -> Speichern -> Schliessen bevor der nächste kommt
Irgendeine Idee ?
Gruss Frank
hi Frank,
Im Endeffekt solls auch nur ein schneller Counter werden.
Lesen -> 1 draufaddieren -> Speichern -> Schliessen bevor der nächste kommtIrgendeine Idee ?
Klaro, immer ;-)
Schnell heißt für mich: Seite ganz normal laden, Zählprozess asynchron abkoppeln. Ergo: Ajax
Schließen bevor der nächste kommt heißt für mich: Transaktionskonzept. Ergo: Datenbankanbindung.
Weitere Ideen hab ich hier:
http://rolfrost.de/cgi-bin/xmlhttpreq.cgi
Aber zurück zu den Dateichen...
Ein umfangreiches PERL-Tutorial findest Du hier:
http://perl-seiten.privat.t-online.de/
Dateien Ein-/Ausgabe:
http://perl-seiten.privat.t-online.de/html/perl_io.html
Btw., es ist für Testzwecke nicht zwingend erforderlich, ein PERL-Script über den Browser als CGI aufzurufen.
Tipp von roro: Teste PERL-Scripts als PERL-Scripts und wenn das alles geht, baue das CGI drumherum.
--roro
Hi --roro
cooles Tutorial, werd ich gleich mal bookmarken :o)
Danke, Frank
Hey,
Im Endeffekt solls auch nur ein schneller Counter werden.
am schnellsten wär's gegangen, wenn du Code wiederverwendet hättest, anstatt mühselig und fehleranfällig das Rad neu zu erfinden. Dafür ist unser CPAN ja da. http://search.cpan.org/dist/File-CounterFile
Hast du die perlfaqs gelesen? Ich glaube, du wirst Teile von perlfaq5 nützlich finden.
Moin,
Im Endeffekt solls auch nur ein schneller Counter werden.
am schnellsten wär's gegangen, wenn du Code wiederverwendet hättest, anstatt mühselig und fehleranfällig das Rad neu zu erfinden. Dafür ist unser CPAN ja da. http://search.cpan.org/dist/File-CounterFile
Warum so kompliziert? In MySQL genügt einen einzige Anweisung um einen Datensatz, für einen Zählerstand, anzulegen oder zu aktualisieren (REPLACE).
Locken von Mehrfachzugriff auf Ressourcen? Dafür gibt es Transaktionssichere Tabellen, der Programmierer braucht sich dabei um nichts zu kümmern.
Scalierbarkeit, für jede Seite eine eigene Zähldatei? Eine Tabelle in der DB für alle URIs.
Dateien zusammensuchen für Reports oder Statistiken? Ein SQL-Statement...
--roro
Warum so kompliziert? In MySQL [...]
Wer CPAN willentlich nicht benutzt, schmeißt sein bestes Wekzeug weg. http://search.cpan.org/dist/DBIx-Counter
Hi Mr. Asia T.,
recht hast Du !
Ich hab dabei nur 2 Probleme.
1. 1und1 hat keins der Module standardmässig installiert
(ich kanns über require oder so versuchen)
und 2.
Mein Hauptproblem überhaupt:
Englisch und ich sind 2 verschiedene Welten :o(
Bis ich da geblickt habe, wie ich irgendwas davon anspreche / abfrage :((
Da komme ich bisher immer nur mit der chinesischen Methode des Kopierens einer definierten Vorlage weiter,
zu mehr reichts noch nicht ...
Aber man lernt ja nie aus (will man ja auch nicht)
und vielleicht krieg ich auch diese Hürde irgenwann geknackt ...
Danke, Frank
Hey,
1und1 hat keins der Module standardmässig installiert
das macht nichts, weil du die Module selber installieren kannst, auch wenn du keine root-Rechte hast. http://cpan.org/misc/cpan-faq.html#How_install_private
ich kanns über require oder so versuchen
Mit use lib
und dem Pfad zu den installierten Modulen.
Englisch und ich sind 2 verschiedene Welten
Schade. Das musst du verbessern, wenn du mehr als unterdurchschnittliche Programmierleistungen erzielen möchtest.
Hi --roro,
hört sich auch gut an.
Ich wollte bisher nur die 85 Millonen (unnützen) Lesezugriffe sparen
und SQL deshalb aussen vor lassen.
Bevor 1und1 deswegen meckert :))
Um Lesen UND Schreiben komme ich bei SQL nicht rum, oder?
Oder gibt es ne spezielle Auto-increment Formm,
wo ich NUR Schreiben muss und SQL erhöht den Wert im Datensatz automatisch um 1 ?
Grüsse, Frank
Hell-O!
Oder gibt es ne spezielle Auto-increment Formm, wo ich NUR Schreiben muss und SQL erhöht den Wert im Datensatz automatisch um 1 ?
Ja, dafür gibt's auto_increment.
Siechfred
Oder gibt es ne spezielle Auto-increment Formm, wo ich NUR Schreiben muss und SQL erhöht den Wert im Datensatz automatisch um 1 ?
Ja, dafür gibt's auto_increment.
Öhm, ich glaube, ich habe da was missverstanden ... :-)
Siechfred
:))
Aber DANKE !
Hallo.
Öhm, ich glaube, ich habe da was missverstanden ... :-)
Frauenversteher?
MfG, at
Oder gibt es ne spezielle Auto-increment Formm,
wo ich NUR Schreiben muss und SQL erhöht den Wert im Datensatz automatisch um 1 ?
z.b. so
UPDATE tabelle SET count = count + 1
Struppi.
Hi Struppi,
KLASSE, das funktioniert ja :o)
Ich denke, mit Allem was hier so steht
krieg ich (für meine Verhältnisse) was Nettes gebastelt.
Danke Euch Allen, Frank
ich habe mal ne Frage zu
http://de.selfhtml.org/perl/funktionen/einausgabe.htm#openDort steht:
+>datei.dat bedeutet: Datei datei.dat zum Lesen und zum Schreiben von Daten öffnen.
Wenn die Datei bereits existiert, wird ihr bisheriger Inhalt überschrieben.
Wenn die Datei noch nicht existiert, wird sie automatisch angelegt.Ich kriege den bisherigen Inhalt aber nicht ausgelesen,
sondern da steht immer nur das zugefügte "Irgendwas" drin :o(
du benutzt keine Module, kein use strict und läßt dir die Warnungewn nicht anzeigen. Das kann u.U. zusätzliche Arbeit für dich bedeuten. wie auch hier.
Wenn du dein Programm mit:
#!/usr/bin/perl -w
startest, hättest du zumindest eine Meldung bekommen warum das falsch läuft.
open(LOG,"+>$dat") || &fehler("Kann <b>$dat</b> nicht lesen.");
Das '&' Zeichen ist veraltet und hat eine spezielle Bedeutung in aktuelen Perlversionen. Im algemeinen ist es überflüssig und du kannst dir noch ausgeben lassen warum das öffnen scheiterte:
open(LOG,"+>$dat") || fehler("Kann <b>$dat</b> nicht lesen.Weil: $!");
Jetzt hast du die Datei geöffnet und der alte Inhalt wird überschrieben.
flock(LOG, 2) || &fehler("Kein Schreib-Lock auf <b>$dat</b>.");
hier ist es sinnvoll use fnctl einzubinden, ich meine du meinst LOCK_EX
$data = <LOG>;
du liest die Zeile an der der Filezeiger steht ein. Da du die Datei überschreiben willst, steht dieser am Anfang und die Datei ist gelöscht.
chomp($data);
Jetzt versuchst du von einem undefinierten Wert das letzte Zeichen (genauer bis zum ersten vorkommen von $/) abzuschneiden.
$data .= "Irgendwas";
und hier hättest du eine Meldung bekommen:
Use of uninitialized value in scalar chomp at xxx.pl line ...
flock(LOG, 8);
das solltest du nicht machen, da ein close() automatisch ein LOCK_UN ausführt und du so hier - zumindest theoretisch - einen parallen Zugriff haben könntest, bis das ...
close(LOG);
ausgeführt wird.
Ws mache ich falsch ?
Oder ist es sowieso besser,
Öffnen->Lesen->Schliessen und dann neu Öffnen->Schreiben->Schliessen ?
Nein, entweder zum anhängen und lesen öffnen open F, "+>>...." und du musst dich dann mit dem Filezeiger (seek) beschäftigen oder mit open F, "+>...." zum lesen und schrieben öffnen, aber dann musst du vorher erst sicherstellen, dass die Datei vorhanden ist.
Struppi.
Hi Struppi.
SUPIE, ganz ganz viel DANKE und eine nach wie vor offene Frage bleibt mir ...
du benutzt keine Module, kein use strict und läßt dir die Warnungewn nicht anzeigen. Das kann u.U. zusätzliche Arbeit für dich bedeuten. wie auch hier.
Wenn du dein Programm mit:
#!/usr/bin/perl -w
startest, hättest du zumindest eine Meldung bekommen warum das falsch läuft.
Bist Du sicher, dass da was kommt ?
Es ist ja noch kein Fehler, wenn nix eingelesen wird, oder ?
open(LOG,"+>$dat") || &fehler("Kann <b>$dat</b> nicht lesen.");
Das '&' Zeichen ist veraltet und hat eine spezielle Bedeutung in aktuelen Perlversionen. Im algemeinen ist es überflüssig und du kannst dir noch ausgeben lassen warum das öffnen scheiterte:
1. Danke
Ich ruf ein sub auf statt die. Wäre vielleicht besser ...
open(LOG,"+>$dat") || fehler("Kann <b>$dat</b> nicht lesen.Weil: $!");
Jetzt hast du die Datei geöffnet und der alte Inhalt wird überschrieben.
Den verstehe ich nicht, weil ich ohne open nicht lesen könnte ...
flock(LOG, 2) || &fehler("Kein Schreib-Lock auf <b>$dat</b>.");
hier ist es sinnvoll use fnctl einzubinden, ich meine du meinst LOCK_EX
Wenn's besser ist, dann 2tes dickes Danke !
$data = <LOG>;
du liest die Zeile an der der Filezeiger steht ein. Da du die Datei überschreiben willst, steht dieser am Anfang und die Datei ist gelöscht.
Versteh ich nicht.
Mir würde die 1. Zeile reichen, an der der Zeiger steht, aber die wird nicht gelesen ...
chomp($data);
Jetzt versuchst du von einem undefinierten Wert das letzte Zeichen (genauer bis zum ersten vorkommen von $/) abzuschneiden.
Joo, falls sich nen Absatz oder so einschleicht ... nicht wirklich nötig ...
$data .= "Irgendwas";
und hier hättest du eine Meldung bekommen:
Use of uninitialized value in scalar chomp at xxx.pl line ...
AAAAH, dickes Danke ... wenns denn so ist.
Ich kann da gern ein my vor $data setzen, aber hab dadurch noch immer nix eingelesen :o(
flock(LOG, 8);
das solltest du nicht machen, da ein close() automatisch ein LOCK_UN ausführt und du so hier - zumindest theoretisch - einen parallen Zugriff haben könntest, bis das ...
close(LOG);
ausgeführt wird.
Das ALLERDICKSTE DANKE !!!
DAS hab ich mich nämlich schon immer gefragt !!!
(wegen dem theoretischen Gedanken ...)
Ws mache ich falsch ?
Oder ist es sowieso besser,
Öffnen->Lesen->Schliessen und dann neu Öffnen->Schreiben->Schliessen ?
Nein, entweder zum anhängen und lesen öffnen open F, "+>>...." und du musst dich dann mit dem Filezeiger (seek) beschäftigen
Sollte ich wirklich mal !
Aber brauch ich das für 1 Zeile einlesen auch ???
oder mit open F, "+>...." zum lesen und schrieben öffnen, aber dann musst du vorher erst sicherstellen, dass die Datei vorhanden ist.
Und das kann ich eben nicht, weil die Datei täglich neu eröffnet werden soll.
Meine Frage bleibt leider.
Warum liest er mit (my) $data = <LOG>; die Datei (1. Zeile) nicht ein.
Versteh ich noch nicht :o(
Ich find auch absolut NIX zu +> im Web (lässt sich auch Sche... nach suchen)
Nutzt das niemand, oder warum ist das so undokumentiert ?
Danke, Frank
du benutzt keine Module, kein use strict und läßt dir die Warnungewn nicht anzeigen. Das kann u.U. zusätzliche Arbeit für dich bedeuten. wie auch hier.
Wenn du dein Programm mit:
#!/usr/bin/perl -w
startest, hättest du zumindest eine Meldung bekommen warum das falsch läuft.Bist Du sicher, dass da was kommt ?
Es ist ja noch kein Fehler, wenn nix eingelesen wird, oder ?
Nein, es its eine Warnung, die aber auf Grund dass die Datei gelöscht wird Auftritt und dir Hinweis gegeben hätte.
open(LOG,"+>$dat") || &fehler("Kann <b>$dat</b> nicht lesen.");
Das '&' Zeichen ist veraltet und hat eine spezielle Bedeutung in aktuelen Perlversionen. Im algemeinen ist es überflüssig und du kannst dir noch ausgeben lassen warum das öffnen scheiterte:
- Danke
Ich ruf ein sub auf statt die. Wäre vielleicht besser ...
Nein, nicht die.
Das '&' Zeichen brauchst du nicht bei einem Funktionsaufruf, wie gesagt es hat eine spezielle Bedeutung, ist aber i.d.R. überflüssig.
open(LOG,"+>$dat") || fehler("Kann <b>$dat</b> nicht lesen.Weil: $!");
Jetzt hast du die Datei geöffnet und der alte Inhalt wird überschrieben.Den verstehe ich nicht, weil ich ohne open nicht lesen könnte ...
Es geht nicht um open, sondern um das '>' Zeichen, damit löscht du einen Inhalt.
flock(LOG, 2) || &fehler("Kein Schreib-Lock auf <b>$dat</b>.");
hier ist es sinnvoll use fnctl einzubinden, ich meine du meinst LOCK_EXWenn's besser ist, dann 2tes dickes Danke !
Du bist damit auf der sicheren Seite, ob es besser ist musst du entscheiden.
$data = <LOG>;
du liest die Zeile an der der Filezeiger steht ein. Da du die Datei überschreiben willst, steht dieser am Anfang und die Datei ist gelöscht.Versteh ich nicht.
Mir würde die 1. Zeile reichen, an der der Zeiger steht, aber die wird nicht gelesen ...
Der Zeiger steht am Dateianfang und die Datei wurde mit '>' gelöscht, daher gibt es keine Zeile.
chomp($data);
Jetzt versuchst du von einem undefinierten Wert das letzte Zeichen (genauer bis zum ersten vorkommen von $/) abzuschneiden.Joo, falls sich nen Absatz oder so einschleicht ... nicht wirklich nötig ...
Wie man's nimmt, es ist kein Fehler ein chomp() zu machen.
$data .= "Irgendwas";
und hier hättest du eine Meldung bekommen:
Use of uninitialized value in scalar chomp at xxx.pl line ...AAAAH, dickes Danke ... wenns denn so ist.
Ich kann da gern ein my vor $data setzen, aber hab dadurch noch immer nix eingelesen :o(
s.o.
flock(LOG, 8);
das solltest du nicht machen, da ein close() automatisch ein LOCK_UN ausführt und du so hier - zumindest theoretisch - einen parallen Zugriff haben könntest, bis das ...
close(LOG);
ausgeführt wird.Das ALLERDICKSTE DANKE !!!
DAS hab ich mich nämlich schon immer gefragt !!!
(wegen dem theoretischen Gedanken ...)
Theoretisch hast du auch das Problem zwischen open() ... und .. flock(). Aber für solche Spezialitäten gibt es bessere Fachleute hier.
Ws mache ich falsch ?
Oder ist es sowieso besser,
Öffnen->Lesen->Schliessen und dann neu Öffnen->Schreiben->Schliessen ?
Nein, entweder zum anhängen und lesen öffnen open F, "+>>...." und du musst dich dann mit dem Filezeiger (seek) beschäftigenSollte ich wirklich mal !
Aber brauch ich das für 1 Zeile einlesen auch ???
Zum einlesen reicht open F, "datei"; wenn nicht schreiben willst....
oder mit open F, "+>...." zum lesen und schrieben öffnen, aber dann musst du vorher erst sicherstellen, dass die Datei vorhanden ist.
Und das kann ich eben nicht, weil die Datei täglich neu eröffnet werden soll.
Was hält dich davon ab erst zu prüfen ob die Datei vorhanden ist und dann diese anzulegen?
z.b. so:
unless(-e $datei)
{
open F, ">$datei"; close F;
}
Meine Frage bleibt leider.
Warum liest er mit (my) $data = <LOG>; die Datei (1. Zeile) nicht ein.
tut es doch.
Versteh ich noch nicht :o(
Weil du sie beim öffnen mit > löscht.
Ich find auch absolut NIX zu +> im Web (lässt sich auch Sche... nach suchen)
Nutzt das niemand, oder warum ist das so undokumentiert ?
Das steht genau so in selfhtml.
Struppi.
Hi Struppi,
schnelle Antwort zu nachtschlafener Zeit, dafür DANKE !
Ansonsten nur no Comment ...
Nochmal zum Anfang:
Dort [url]http://de.selfhtml.org/perl/funktionen/einausgabe.htm#open[/url] steht:
+>datei.dat bedeutet: Datei datei.dat zum Lesen und zum Schreiben von Daten öffnen.
Du schreibst:
open(LOG,"+>$dat") || fehler("Kann <b>$dat</b> nicht lesen.Weil: $!");
Jetzt hast du die Datei geöffnet und der alte Inhalt wird überschrieben.
Den verstehe ich nicht, weil ich ohne open nicht lesen könnte ...
Es geht nicht um open, sondern um das '>' Zeichen, damit löscht du einen Inhalt.
Ist das jetzt ein Bug oder was ?
Möchtest Du ihn melden ?!
Es gibt noch 1-2 Englisch-Seiten :o(, die meinen, dass das geht.
ICH möcht eigentlich nur wissen, ob man mit +> einlesen kann, oder nicht.
Das kann doch nicht immer so kompliziert sein.
Ein einfaches "Geht nicht" würd mir reichen ...
Danke, Frank
P.s.: Sorry, Dank Dir,
aber ich hab die letzten 5 Stunden mit dieser Frage vergeudet.
Hell-O!
Dort http://de.selfhtml.org/perl/funktionen/einausgabe.htm#open steht:
+>datei.dat bedeutet: Datei datei.dat zum Lesen und zum Schreiben von Daten öffnen.
Ich denke, dass da die http://perldoc.perl.org/functions/open.htmlPerldokumentation aussagekräftiger ist:
"If MODE is '>' , the file is truncated and opened for output, being created if necessary."
Und weiter:
"You can put a '+' in front of the '>' ... to indicate that you want both read and write access to the file ... the '+>' mode would clobber the file first."
Heißt im Klartext: Wenn du den Modus '>' verwendest, wird der Dateizeiger am Anfang der Datei positioniert. Sollte die Datei nicht existieren, wird sie angelegt. Verwendest du den Modus '+>', ist das Verhalten wie beschrieben, die Datei wird jedoch zuerst geleert.
ICH möcht eigentlich nur wissen, ob man mit +> einlesen kann, oder nicht.
Ja, aber eine leere Datei. Ergo ist dieser Modus für dein Vorhaben nicht geeignet. Du müsstest es mit dem Modus '+>>' und seek in Kombination mit truncate probieren:
# Datei zum anhängenden I/O öffnen
open FH, '+>>', $datei || die $!;
flock FH, LOCK_EX;
# Dateizeiger am Anfang positionieren
seek FH, 0, 0;
# Alte Daten auslesen
my $old_data = <FH>;
# wieder zurück zum Anfang
seek FH, 0, 0;
# Datei abschneiden
truncate FH, 0;
# neue Daten reinschreiben
print FH 'Some new data';
# zurück zum Anfang
seek FH, 0, 0;
# Einlesen der neuen Daten zur Kontrolle
my $new_data = <FH>;
close FH;
# Ausgabe:
print 'old data: ', $old_data, "\n";
print 'new data: ', $new_data, "\n";
Oder einfach zweimal öffnen, einmal zum Lesen und einmal zum Schreiben.
Siechfred
Variante 2, damit sparst du eine seek-Anweisung:
open FH, '+<', $datei || die $!;
my $old_data = <FH>;
seek FH, 0, 0;
truncate FH, 0;
print FH 'Some new data';
seek FH, 0, 0;
my $new_data = <FH>;
close FH;
Vorteil der ersten Variante ist, dass die Datei automatisch angelegt wird, wenn sie noch nicht existiert, dies geschieht bei der zweiten Variante nicht. Dafür wird bei ihr der Dateizeiger von Haus aus am Anfang der Datei positioniert. Welche nun die bessere für dein Vorhaben ist, musst du entscheiden. Wichtig ist auf jeden Fall die truncate-Anweisung, wenn du nicht sicherstellen kannst, dass die alten und die neuen Daten nicht die gleiche Länge haben.
Siechfred
Danke Siechfred,
hört sich gut an :o)
Version 1 (wegen automatischer Neuanlage) werd ich mal testen ...
Grüsse, Frank