Michael Huhn: gzcompress für leere 1GB-Dateien

Ich brauche für ein php-Programm eine gepackte Version von sehr großen (auch über 1 GB) Dateien, die leer sind, d.h. nur aus Leerzeichen bestehen. In meinem Programm habe ich zur Zeit

gzcompress(str_pad("",$intLen));

stehen, was bei Dateien bis 200 MB zwar lange dauert aber noch funktioniert. Bei größeren Dateien tötet mir dieser Befehl jedoch das ganze System und es kommt nichts mehr dabei heraus. Ich habe versucht, die Ausgabe der gzcompress für leere Daten zu interpretieren, da ich mir dachte, derart einfache Dateien seien auch gepackt einfach lesbar, was aber nicht der Fall war.

Wo finde ich/wie programmiere ich eine Funktion die mir leere Strings performant in gzip-Format umwandelt?

  1. Ich brauche für ein php-Programm eine gepackte Version von sehr großen (auch über 1 GB) Dateien, die leer sind, d.h. nur aus Leerzeichen bestehen. In meinem Programm habe ich zur Zeit

    gzcompress(str_pad("",$intLen));

    stehen, was bei Dateien bis 200 MB zwar lange dauert aber noch funktioniert. Bei größeren Dateien tötet mir dieser Befehl jedoch das ganze System und es kommt nichts mehr dabei heraus. Ich habe versucht, die Ausgabe der gzcompress für leere Daten zu interpretieren, da ich mir dachte, derart einfache Dateien seien auch gepackt einfach lesbar, was aber nicht der Fall war.

    Wo finde ich/wie programmiere ich eine Funktion die mir leere Strings performant in gzip-Format umwandelt?

    Das Format ist zwar in RFCs beschrieben (mit allem drum und dran drei Stück, sollten sicher irgendwo unter http://www.gzip.org zu finden sein), aber bei den Datenmassen wird Dir eine in PHP geschriebene gzip-Funktion nicht viel Freude bereiten; dazu ist PHP zu langsam (Interpretersprache) und wahrscheinlich auch viel zu einfach aufgebaut (verfügbare bzw. verlässliche Datentypen).

    Du solltest vielleicht besser versuchen, Deine Daten in einer Datei zu speichern und die dann via exec() vom gzip-Programm verwursten zu lassen.

    Gruß,
      soenk.e

    1. Das Format ist zwar in RFCs beschrieben (mit allem drum und dran drei Stück, sollten sicher irgendwo unter http://www.gzip.org zu finden sein), aber bei den Datenmassen wird Dir eine in PHP geschriebene gzip-Funktion nicht viel Freude bereiten;

      Ich würde ja wenn es irgendwie geht nicht den normalen Algorithmus nehmen da der ja nicht den Wissensvorsprung nutzt, dass die Dateien leer sind.

      Du solltest vielleicht besser versuchen, Deine Daten in einer Datei zu speichern und die dann via exec() vom gzip-Programm verwursten zu lassen.

      Dann müsste ich während der Laufzeit 1 GB auf die Platte schreiben und dann noch auf die Komprimierung warten :-(

      gruß
      mhuhn

      1. Das Format ist zwar in RFCs beschrieben (mit allem drum und dran drei Stück, sollten sicher irgendwo unter http://www.gzip.org zu finden sein), aber bei den Datenmassen wird Dir eine in PHP geschriebene gzip-Funktion nicht viel Freude bereiten;

        Ich würde ja wenn es irgendwie geht nicht den normalen Algorithmus nehmen da der ja nicht den Wissensvorsprung nutzt, dass die Dateien leer sind.

        Es steht Dir frei, anhand der Informationen über den Aufbau des Formats eine passende Routine zu schreiben.

        Du solltest vielleicht besser versuchen, Deine Daten in einer Datei zu speichern und die dann via exec() vom gzip-Programm verwursten zu lassen.

        Dann müsste ich während der Laufzeit 1 GB auf die Platte schreiben und dann noch auf die Komprimierung warten :-(

        Ja, und? Du erwartest doch nicht allen ernstes, daß eine mittels Interpreter auszuführende Komprimierungsfunktion schneller ist als ein in Maschinensprache vorliegendes, d.h. fertig für den Prozessor übersetztes Programm? Und Du erwartest doch nicht etwa, daß der Rechner von einer 1 GByte großen Datei (möglicherweise auf einer 80 GByte-Platte), die stückweise verarbeitet werden kann, weniger belastet wird als von einem 1 GByte großen Datenblock, der komplett im Speicher (von möglicherweise "nur" 512 MByte Umfang) gehalten werden muß?

        Gruß,
          soenk.e

      2. Moin,

        Dann müsste ich während der Laufzeit 1 GB auf die Platte schreiben und dann noch auf die Komprimierung warten :-(

        Ein bisschen Shell-Magie kann dir zumindest beim ersten Teil helfen:

        dd if=/dev/zero bs=1K count=1M | gzip -c > groß.gz

        Ich kenne deine Anwendung nicht, aber wenn es auch ein .zip tut, google mal nach 42.zip, das ist eine gepackte Datei die entpackt (IIRC) 4 Gigabytes groß wird.

        --
        Henryk Plötz
        Grüße aus Berlin

        1. Ein bisschen Shell-Magie kann dir zumindest beim ersten Teil helfen:

          dd if=/dev/zero bs=1K count=1M | gzip -c > groß.gz

          Sorry, ich zähle mich zu den Windows-phplern. Außerdem brauche ich das während der Laufzeit und da ist halt nix mit Shell :)

          Ich kenne deine Anwendung nicht, aber wenn es auch ein .zip tut, google mal nach 42.zip, das ist eine gepackte Datei die entpackt (IIRC) 4 Gigabytes groß wird.

          Ich muss während der Laufzeit solche Dateien erzeugen. Es geht darum, in einer ZIP-Datei nachsehen zu können, wir groß eine Datei ist, ohne die ZIP dabei groß werden zu lassen.

          Ich habe mir jetzt damit geholfen, die größe auf 1/1000 zu reduzieren, jetzt muss ich halt die angaben in KB als MB lesen, aber sehr elegant ist das nicht :-(

          1. Moin!

            Ein bisschen Shell-Magie kann dir zumindest beim ersten Teil helfen:

            dd if=/dev/zero bs=1K count=1M | gzip -c > groß.gz

            Sorry, ich zähle mich zu den Windows-phplern. Außerdem brauche ich das während der Laufzeit und da ist halt nix mit Shell :)

            exec() würde wohl auch funktionieren - nur dd eben nicht unter Windows.

            Ich muss während der Laufzeit solche Dateien erzeugen. Es geht darum, in einer ZIP-Datei nachsehen zu können, wir groß eine Datei ist, ohne die ZIP dabei groß werden zu lassen.

            Die Aufgabe verstehe ich nicht - und auch nicht deinen Lösungsansatz. Komprimierte Daten sind immer unterschiedlich groß. Ich sehe nicht, wie du mit einer komprimierten gzip-Datei irgendwelche Vergleiche anstellen willst mit ZIP-Dateien.

            Ich habe mir jetzt damit geholfen, die größe auf 1/1000 zu reduzieren, jetzt muss ich halt die angaben in KB als MB lesen, aber sehr elegant ist das nicht :-(

            Dein Lösungsansatz ist vermutlich vollkommen wirr. Was willst du eigentlich wirklich machen? Mit den Kommandozeilenkommandos für PKZIP (und bestimmt auch gzip) kannst du die Inhalte einer ZIP-Datei auflisten lassen - auch die enthaltene Dateigröße in gepackt und ungepackt. Die Ausgabe des Befehls müßtest du nur noch parsen/auseinandernehmen und dann weiterbehandeln.

            - Sven Rautenberg