Thread open-Anweisung (22 answers)
Opened by geloescht at 2012-06-24 00:30

topeg
 2012-06-24 01:31
#159327 #159327
User since
2006-07-10
2611 Artikel
BenutzerIn

user image
Hier zwei kommentierte Funktionen zum nutzen von geschützten Zählern:
more (18.6kb):
Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# das Modul enthält Funktionen und Werte,
# die man Braucht um Dateien zu Manipulieren.
# Speziell brauchen wir hier "LOCK_EX" und "LOCK_UN"
# ':flock' ist ein Befehl an das Modul
# und macht diese Werte Verfügbar.
use Fcntl ':flock';

# Funktion zum lesen des Zählerwerts
sub read_counter
{
  # Dateiname des Zählers muss übergeben werden
  my $file = shift( @_ );

  # hier drin wird der Counterwert gespeichert
  # "undef" bedeutet das der wert zur zeit nicht definiert ist
  # testet man das mit "defined($counter)" so ist das False
  my $counter = undef;

  # wenn das lesend öffnen der Datei erfolgreich war.
  # open liefert "true" zurück wenn das öffnen ein Erfolg war.
  if( open(my $fh, '<', $file) )
  {
    # Die Datei wird exklusiv gesperrt.
    # das funktioniert nur wenn alle Programme,
    # die auf die Datei zugreifen, das machen.
    # Perl fragt hier alle anderen Prozesse,
    # die auf diese Datei zugreifen,
    # ob einer sie schon gesperrt hat.
    # Wenn dem so ist wartet Perl solange bis die Sperrung aufgehoben wurde.
    # danach beansprucht Perl die Datei für diesen Prozess.
    flock($fh, LOCK_EX);

    # den Wert in der Datei lesen
    $counter=<$fh>;

    # sperrung aufheben, damit andere die Datei nutzen können
    flock($fh, LOCK_UN);

    # Datei Schließen
    close($fh);
  }

  # es wird der aktuelle Counterwert zurück gegeben
  return $counter;
}

# diese Funktion öffnet die Datei,
# ließt den Zählerwert und erhöht ihn um 1
sub incement_counter
{
  # Pfad zur Datei muss genannt werden
  my $file = shift( @_ );

  # der Zähler wird erst mal auf "undef" gesetzt
  my $counter = undef;

  # Das FileHandle, welches zum lesen/schreiben
  # der Zählerwerte benutzt werden soll
  #
  # Es ist eine Vereinbarung das Filehandles,
  # die keinen speziellen Namen brauchen,
  # als "$fh" oder "FH" benannt werden.
  # das macht es anderen Lesern einfacher zu erkennen was gemeint ist
  #
  # seit Perl5 ist es möglich Dateihandles auch in Variablen zu packen
  # damit lassen sie sich auch in Arrays etc. nutzen
  # als interessanter Nebeneffekt wird das Filehandle automatisch geschlossen,
  # wenn die Variable gelöscht wird.
  # Scripte werden damit weniger Fehleranfälliger.
  my $fh=undef;

  # Wenn die Datei Existiert
  if(-f $file)
  {
    # wenn das Öffnen zum lesen und schreiben erfolgreich war
    if( open($fh, '+<', $file ) )
    {
      # Die Datei Sperren
      flock( $fh, LOCK_EX );

      # den aktuellen Wert lesen
      $counter=<$fh>;

      # Den Lese und Schreib-Punkt an den Anfang der Datei setzen
      # jedes Filehandle hat einen Zeiger der anzeigt,
      # wo in der Datei die nächsten Daten gelesen werden soll.
      # dieser Befehl besagt: vom Anfang der Datei aus gesehen
      # setze den Zeiger auf 0
      seek( $fh, 0, 0 );

      # die Größe der Datei auf 0 setzen
      # damit wird der Inhalt der Datei gelöscht
      truncate( $fh, 0 );

    }
  }
  # die Datei existiert nicht
  else
  {
    # wenn die Datei schreibend geöffnet werden kann.
    if( open( $fh, '>', $file ) )
    {
      # Die Datei sperren
      flock( $fh, LOCK_EX );

      # den Zähler auf -1 setzen
      $counter = -1;
    }
  }

  # wenn $fh einen Wert enthält,
  # dann konnte die Datei geöffnet werden
  if( $fh )
  {
    #den zähler um 1 erhöhen
    $counter++;

    # neuen wert in die Datei schreiben
    print $fh $counter;

    # Sperrung aufheben
    flock( $fh, LOCK_UN );

    # Datei schließen
    close( $fh );
  }

  # es wird der aktuelle Counterwert zurück gegeben
  return $counter;
}



Beispielanwendung:

Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
my $counter_file='counter.txt'

my $cnt=read_counter($counter_file);

# wenn das lesen nicht erfolgreich war
# wird von read_counter "undef" in $cnt geschrieben
# wenn man das testet,
# kann man heraus finden,
# ob das lesen erfolgreich war.
# die Fehlermeldung der letzten Dateiaktion
# steht in der Spezialvariable: "$!"
die("Konnte Zähler nicht lesen $!\n") unless( defined ( $cnt ) );

print "COUNTER: $cnt\n";

$cnt=incement_counter($counter_file);

die("Konnte Zähler nicht lesen $!\n") unless( defined ( $cnt ) );

print "COUNTER: $cnt\n";



Edit: Einen Fehler im Open-Modus korrigiert es heißt "+<" und nicht "<+" das kann ich mir nie merken. :-/
Last edited: 2012-06-24 01:47:58 +0200 (CEST)

View full thread open-Anweisung