Textdatei schreiben haut nicht hin!
Arno
- cgi
Hallo!
Ich möchte gerne für meine Seite eine kleine Statistik machen, also wo die Leute herkommen, wieviele Besucher usw. Das ganze soll für ca. 200 CGI generierte Seiten erfolgen.
Naja ist ja kein Problem, dachte ich. Mein CGI schreibt also bei jedem Aufruf einer Seite die gewünschten Daten in ein TXT File.
Ich lese das txt file erst mal ein. verändere ein bisserl was und schreibe es dann wieder raus (zeilenweise)
Das Problem ist jetzt, dass irgendwie das File verhundst wird auch wenn alles zu gehen scheint. Gestern hatte ich 260 Zeilen (Da 260 Besucher), heute hatte ich dann nur mehr 130! Der rest war verschwunden. Da haut also was mit aulesen, verändern und wieder schreiben nicht hin.
Meine Testläufe haben keine Fehler ergeben (ich hab halt keine gefunden). Naja wenn ich ganz oft auf reload (schnell hintereinander) drücke wird die erste Zeile verunstaltet. Kann es sein, dass der Besucher, wenn er ungeduldig ist, das CGI gerade wärend des schreibens abbricht??? Das ist halt meine Vermutung, da ich sonst keine Idee habe was es sein könnte!
Bitte helft mir! Wäre mir sehr wichtig!
Danke
hallo arno,
ich erlaubbe mir auf die self html forums faq zu verweisen
http://forum.de.selfhtml.org/faq/#Q-07
so kann dir schlecht jemand helfen ohne quelltext.
mfg
sven
Sorry! Hier also der Source Code. Ich hoffe ihr kennt euch aus, hab ein bischen unschän programmiert befürchte ich. Vielleicht ist mir ja trotzdem noch zu helfen ;o)
#!/usr/bin/perl
use CGI qw(:standard);
@Spiele = (""); # Speicher für alle Datensaetze
@Datensatz = (""); # Speicher für alle Felder des aktuellen Datensatzes
@Stat2 = ("");
$Jetztwert = time();
$Jetztzeit = localtime($Jetztwert);
@Zeit = split(/ +/,$Jetztzeit);
@Uhrzeit = split(/:/,$Zeit[3]);
#------------- Einlesen der Daten ------------
open(SPIELE, "<spiele.txt") || die "Spieledatei nicht gefunden\n";
while(<SPIELE>)
{
if($i == 0)
{
$Felder = $_;
}
else
{
$Spiele[$i] = $_;
}
$i++;
}
close(SPIELE);
chop($Felder);
@Datenfelder = split(/ƒ/,$Felder);
#------------- Einlesen der Statistikdatei ------------
$i=0;
open(STAT2, "<stat2.txt") || die "Statistikdatei nicht gefunden\n";
while(<STAT2>)
{
$Stat2[$i] = $_;
$i++;
}
close(STAT2);
#------------- Schreiben der Statistiksatei ------------
$i=0;
open(STAT2, ">stat2.txt") || die "Statistikdatei 2 nicht gefunden\n";
for(@Stat2) # solange Daten in der Adressenliste sind
{
@StatDatensatz2 = split(/ƒ/,$_); # Aktuellen Datensatz aufdröseln
if ($StatDatensatz2[0] ne "123") {
if ($i>0) {
print STAT2 ("\n");
}
print STAT2 $StatDatensatz2[0];print STAT2 "ƒ";
print STAT2 $StatDatensatz2[1];print STAT2 "ƒ";
print STAT2 $StatDatensatz2[2];print STAT2 "ƒ";
print STAT2 $StatDatensatz2[3];print STAT2 "ƒ";
print STAT2 $StatDatensatz2[4];print STAT2 "ƒ";
print STAT2 $StatDatensatz2[5];print STAT2 "ƒ";
print STAT2 $StatDatensatz2[6];print STAT2 "ƒ";
print STAT2 $StatDatensatz2[7];print STAT2 "ƒ";
print STAT2 $StatDatensatz2[8];print STAT2 "ƒ";
print STAT2 $StatDatensatz2[9];print STAT2 "ƒ";
print STAT2 $StatDatensatz2[10];print STAT2 "ƒ";
print STAT2 $StatDatensatz2[11];print STAT2 "ƒ";
}
$i++;
}
&menu;
for(@Spiele)
{
@Datensatz = split(/ƒ/,$_);
$i = 0;
if ($Datensatz[0] eq param('Spiel')){
#Neuer Statistikeintrag -----------
print STAT2 "\n"; print STAT2 "$Datensatz[0]ƒ$Datensatz[1]ƒ1ƒ$Zeit[0]ƒ$Zeit[1]ƒ$Zeit[2]ƒ$Zeit[3]ƒ";
print STAT2 $ENV{'REMOTE_ADDR'};print STAT2 "ƒ";
print STAT2 $ENV{'REMOTE_HOST'};print STAT2 "ƒ";
print STAT2 $ENV{'REMOTE_USER'};print STAT2 "ƒ";
print STAT2 $ENV{'HTTP_REFERER'};print STAT2 "ƒ";
print STAT2 $ENV{'HTTP_ACCEPT_LANGUAGE'};print STAT2 "ƒ";
close(STAT2);
#ENDE Neuer Statistikeintrag -----------
Hi Arno,
versuche mal, geistig einen Schritt weg von der konkreten Lösung zu
machen - das ganze Perl ist mir alles viel zu konkret.
Du liest Daten aus einer Datei ein und schreibst anschließend Daten
in dieselbe Datei zurück. Wenn das mehrere Besucher gleichzeitig tun,
dann bekommst Du Probleme.
Ich würde die Sache also auf einer wesentlich abstrakteren Ebene angehen:
Richtiges Programmieren ist etwas mehr, als ein paar Befehle hinzuschreiben.
Viele Grüße
Michael
Hallo!
Nun ja, ich möchte eine Statistik für meine Homepage machen. Also wenn wir mal nur davon ausgehen, dass ich die Besucheranzahl erhöhen will, so muss ich den aktuellen Stand zuerst auslesen, dann bearbeiten (eins erhöhen) und wieder abspeichern.
d.h. für die Architektur:
ad 1.) Ja ich brauche die Daten der Datei um "neue" zu schreiben. Ein anhängendes Schreiben kommt also nicht in Frage.
ad. 2) Wie gesagt: Ich öffne die Datei (lesen) und lese mal alle Daten aus. Ich schließe die Datei.
Ich verändere alle Daten die ich ändern will (z.B. Besucheranzahl)
Ich öffne die Datei (schreiben) und schreibe alle Datei in die Datei. Ich schließe die Datei.
ad 3.) Ja alle Benutzer müssen auf die selbe Datei zugreifen.
lg
Arno
Hi Arno,
Nun ja, ich möchte eine Statistik für meine Homepage machen.
Warum willst Du dafür die Zugriffe selbst erfassen?
Reichen Dir die Informationen nicht, welche Dein Webserver bereits erfaßt?
(http://webalizer.teamone.de/selfforum/)
Viele Grüße
Michael
Huhu Arno
das riecht irgendwie nach mit-ohne-file-locking gekocht, oder?
Viele Grüße
lulu
Das Problem ist jetzt, dass irgendwie das File verhundst wird auch wenn alles zu gehen scheint. Gestern hatte ich 260 Zeilen (Da 260 Besucher), heute hatte ich dann nur mehr 130! Der rest war verschwunden. Da haut also was mit aulesen, verändern und wieder schreiben nicht hin.
File locking klingt gut! :o)
Hab ich nicht gemacht! Habs einfach geöffnet, offen gelassen so lang ichs brauch, geschrieben und dann geschlossen.
Okay, ich werd mal selfhtml durchforsten, da steht sich was über filelocking drinnen nehm ich an!
vielen Dank vorerst
Huhu Arno
das riecht irgendwie nach mit-ohne-file-locking gekocht, oder?
Viele Grüße
lulu
Das Problem ist jetzt, dass irgendwie das File verhundst wird auch wenn alles zu gehen scheint. Gestern hatte ich 260 Zeilen (Da 260 Besucher), heute hatte ich dann nur mehr 130! Der rest war verschwunden. Da haut also was mit aulesen, verändern und wieder schreiben nicht hin.
Die Zeilen beim öffnen der Datei sehen nun so aus:
open(STAT2, "<stat2.txt") || die "Statistikdatei nicht gefunden\n";
flock(STAT2, LOCK_EX);
Ich hoffe das behebt mein Problem!
Hoi,
Die Zeilen beim öffnen der Datei sehen nun so aus:
open(STAT2, "<stat2.txt") || die "Statistikdatei nicht gefunden\n";
flock(STAT2, LOCK_EX);
Ich hoffe das behebt mein Problem!
Nein, wird es nicht. Wenn der User auf ESC drueckt, kann es durchaus
sein, dass das Script terminiert wird, bevor es fertig ist mit
schreiben. Siehe dazu auch
http://forum.de.selfhtml.org/archiv/2002/1/2616/
Gruesse,
CK
Okay, also in der theorie hab ich deine ausführliche Erklärung halbwegs verstanden!
Aber wo gehört ...
my $pid = fork;
unless($pid) {
die 'could not fork!' unless defined $pid;
# process is no longer a child
die 'could not remove session' unless setsid;
}
else {
# main process ends
exit 0;
}
nun genau hin? Im Source Code mein ich?
Ist wahrscheinlich eine blöde Frage oder? Sorry!
Hoi, <-- Begruessung
Okay, also in der theorie hab ich deine ausführliche Erklärung
halbwegs verstanden!
Gut.
Aber wo gehört ...
my $pid = fork;
unless($pid) {
die 'could not fork!' unless defined $pid;
# process is no longer a child
die 'could not remove session' unless setsid;
}
else {
# main process ends
exit 0;
}
nun genau hin? Im Source Code mein ich?
Unter die letzte Ausgabe. Das Schreiben musst du halt zuletzt machen.
Ist wahrscheinlich eine blöde Frage oder? Sorry!
Es gibt keine bloeden Fragen, hoechstens ueberfluessige. Und diese
wars nicht.
Gruesse,
CK