Candid Dauth: Kompression via Mainstream-Extension

Beitrag lesen

Heißa, alle,

Ich habe einige Dateien, die ein serialisiertes Array enthalten, das dann von einem Objekt in PHP5 verwaltet wird. Solange das Objekt besteht, soll die Datei gesperrt bleiben, und die Datei wird beim Erstellen des Objekts komplett ausgelesen und unserialisiert, beim Löschen des Objekts wird das Array wieder serialisiert und voll in die Datei gespeichert, andere Dateioperationen werden nicht gebraucht.

function __construct($user)  
{  
  $this->filename = DB_DIR.'/'.urlencode($user);  
  $stream = '';  
  $this->location = $stream.$this->filename;  
  $this->file_pointer = fopen($this->location, 'r+b');  
  flock($this->file_pointer, LOCK_EX);  
  clearstatcache();  
  $this->raw = unserialize(fread($this->file_pointer, filesize($this->filename));  
}  
  
function __destruct()  
{  
  fseek($this->file_pointer, 0, SEEK_SET);  
  ftruncate($this->file_pointer, 0);  
  fwrite($this->file_pointer, serialize($this->raw));  
  flock($this->file_pointer, LOCK_UN);  
  fclose($this->file_pointer);  
}

So weit, so gut, das funktioniert bisher auch problemlos.

Da jedoch letztendlich sehr viele solche Dateien existieren, sind die Datenmengen auch recht groß, und ich wollte nun auf Kompression setzen.
Mit bzip2 habe ich da bisher die besten Erfahrungen bezüglich des Kompressionslevels gemacht. Das ist zwar ein bisschen CPU-intensiver als gzip, aber das macht mir nichts aus.

Ich setze also $stream auf 'compress.bzip2://'. Jetzt tritt dabei folgendes Problem auf: Ich erhalte in der Funktion __destruct() eine Fehlermeldung, dass bzip2 kein fseek unterstützt. Eigentlich dürfte es doch kein Problem sein, wieder an den Anfang der Datei zu springen bzw. deren Inhalt zurückzusetzen. Neu öffnen will ich nicht, da sie ja in der Zeit dann ungesperrt ist, was zum Chaos führen würde. Gibt es eine spezielle Möglichkeit, den Inhalt der Datei zurückzusetzen?
Außerdem stimmt das mit der filesize nicht, da die Dateigröße der bzip2-Datei ja anders ist als die Größe ihres Inhalts. Gibt es da eine Funktion, mit der ich die Größe des Inhalts der bzip2-Datei herausbekomme oder anderswie ihren gesamten Inhalt auslese?

Wenn ich alternativ 'compress.zlib://', also gzip-Kompression, verwende, tritt ein ganz anderes Problem auf: Die Datei lässt sich anscheinend nicht zum Lesen und Schreiben gleichzeitig öffnen. Ich müsste sie also wieder schließen, um sie neu zu beschreiben, und das gefällt mir nicht, da ich sie ja dann wieder entsperren muss.

Die Sache mit gzopen() habe ich auch schon ausprobiert, der Nachteil dort ist aber, dass sich die Dateien anscheinend nicht sperren lassen kann, und außerdem habe ich keine generalisierten Zugriffsfunktionen, wenn ich mal das Kompressionsformat ändern will.

Eine Möglichkeit, die mir jetzt einfällt, ist, zusätzliche Dateien anzulegen, die nur zur Sperrung dienen. Allerdings würden dadurch noch viel mehr Dateien entstehen, das passt mir also auch nicht so recht.

Fällt jemandem eine anständige Lösung für mein Problem ein? Oder werde ich meine eigenen Streams schreiben müssen?

Gautera!
Grüße aus Biberach Riss,
Candid Dauth

--
Ein Fußball-Fan? Noch auf der Suche eine Schlafmöglichkeit im Großraum Stuttgart für die WM 2006? Wie wäre es mit Herrenberg, einer gemütlichen Kleinstadt am Rande des Schönbuchs – von der Lage her ideal, auch für andere Vorhaben im Urlaub. Ferienwohnungen-Herrenberg.com.
http://cdauth.de/