Tom: Mehrere modi für fopen

Beitrag lesen

Hello,

Du braucht vor allem eine Locking-Strategie. Die íst in Deinem Fall aber noch ganz einfach.

Benutze einfach die Funktion:

#------------------------------------------------------------------------------

Funktion softlock()

#------------------------------------------------------------------------------

Datei im Lock Modus $lockmode öffnen und Handle zurückgeben

W, WRITE  = Lock Exclusive und (rb+)

R, READ   = Lock Shared    und (rb)

C, Create = Try to Create and lock exclusive (xb+)

function softlock( $lockfile_name,             ## Qualifizierter Dateiname
                   $mode,                      ## Öffnungs- und Sperranforderung wie oben
                   &$lastwrite,                ## Letztes Aktualisierungsdatum
                   &$error_no                  ## Duchgeschleifter Fehler
                 )
{
  $php_errormsg ='';                           ## ist nicht angelegt, solange
                                               ## kein Fehler auftrat
  $lastwrite = false;                          ## kein Modifikationsdatum vorhanden

if ($error_no > 0) return false;             ## Bei Vorfehler abbrechen

## Lockmode feststellen
  $lockmode = strtoupper($mode);

if ($mode == 'W')
  {
    $openmode = 'rb+';
    $lockmode = LOCK_EX;
  }
  elseif ($mode == 'C')
  {
    $openmode = 'xb+';
    $error_no = 8;                               ## Datei wurde angelegt
    $lockmode = LOCK_EX;
  }
  elseif($mode == 'R')
  {
    $openmode = 'rb';
    $lockmode = LOCK_SH;
  }
  else
  {
    $error_no = 100;                             ## falsche Funktionsnutzung
    return false;
  }

## Dateihandle beschaffen

for ($x=0;$x<5;$x++)                           ## Schleife 5 mal durchlaufen
  {
    clearstatcache();
    $php_errormsg = '';

if($lh = @fopen($lockfile_name,$openmode))
    {
      $error_no = 0;
      break;                                     ## oder bei Erfolg abbrechen
    }
    else
    {
      $errormsg = strtolower($php_errormsg);

if(strpos($errormsg,'invalid argument')!==false)
      {
        $error_no = 101;                         ## hier könnte man auch überlegen
        $openmode = 'a+';                        ## es doch mit rb+ zu versuchen

if ($fh1 = fopen($lockfile_name,$openmode))
        {
          $openmode = 'rb+';                     ## es doch mit rb+ zu versuchen
          fclose($fh1);                          ## Hilfshandle wieder abgeben
          $error_no = 8;
        }
        else
        return false;
      }
      elseif(strpos($errormsg,'illegal operation argument')!==false)
      {
        $error_no = 101;
        $openmode = 'a+';                        ## Datei hilfsweise mit a+ anlegen

if ($fh1 = fopen($lockfile_name,$openmode))
        {
          $openmode = 'rb+';                     ## es doch mit rb+ zu versuchen
          fclose($fh1);                          ## Hilfshandle wieder abgeben
          $error_no = 8;
        }
        else
        return false;
      }
      elseif(strpos($errormsg,'no such file or directory')!==false)
      {
        $error_no = 2;
        return false;
      }
      elseif(strpos($errormsg,'permission denied')!==false and $error_no == 8)
      {
        return false;              ## damit Fehler 8 überhaupt nach draußen kommt
      }
      elseif(strpos($errormsg,'permission denied')!==false)
      {
        $error_no = 5;
        return false;
      }
      elseif(strpos($errormsg,'file exists')!==false)
      {
        $openmode = 'rb+';
      }
    }
    ## zur Zeit sind fopen() und dio_open() noch nicht aufeinander abgestimmt
    ## Eine Verzögerung beim Öffen ist daher noch nicht sinnvoll

#usleep(8000);                               ## 8ms warten bis zum nächsten
  }                                              ## Öffnungsversuch

if (!$lh)
  {
    $error_no = 5;                               ## konnte Datei nicht öffnen
    return false;                                ## bei Misserfolg Funktionsende
  }

# Lockversuch
  for ($x=0;$x<5;$x++)
  {
    if (@flock($lh,$lockmode + LOCK_NB))
    {
      $lastwrite = filemtime($lockfile_name);    ## letzes Modifikationsdatum
      return $lh;
    }
    usleep(8000);  ## 8ms warten bis zum nächsten Versuch
  }

$error_no = 6;                                 ## konnte Datei nicht sperren
  fclose($lh);
  return false;
}

Wenn die ein Handle zurückliefert, kannst Du arbeiten, wenn nicht, musast Du halt den Fehler auswerten. Ich habe zum Thema "Dateiöffnung " und "Locking" immer noch einen dreiviertelfertige Artikel hier rumfliegen. Ich komme einfach nicht dazu, dafür mal die Grafiken anzufertigen zum Thema "Zeitverhalten".

Harzliche Grüße aus http://www.annerschbarrich.de

Tom

--
Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
Nur selber lernen macht schlau