gzopen, gzwrite, gzread
Tom
- php
Hello,
zu den gz-Funktionen von PHP gibt es hier im Archiv leider nur zweieinhalb Threads. Aber vielleicht kann mir trotzdem jemand helfen?
Muss man ein File, das man mit gzwrite beschreiben will, unbedingt mit gzopen() öffnen, oder geht da auch fopen(...,ab+) ?
Wenn es 'zufällig' funktioniert, muss es ja nicht richtig sein.
Liebe Grüße aus http://www.braunschweig.de
Tom
Moin!
Muss man ein File, das man mit gzwrite beschreiben will, unbedingt mit gzopen() öffnen, oder geht da auch fopen(...,ab+) ?
Wenn es 'zufällig' funktioniert, muss es ja nicht richtig sein.
Die Doku eröffnet diese Möglichkeit eigentlich nicht. Wenns geht, dann liegt das wohl eher daran, dass die internen Strukturen (Filepointer etc.) gleich sind, aber man weiß ja nie, was doch noch im Geheimen passiert.
Die gz*-Funktionen liefern aber bei unkomprimierten Dateien immer den unveränderten Datenstrom, so dass auf fopen() & Co. eigentlich verzichtet werden kann - sofern man nicht unkomprimierte Dateien schreiben will.
- Sven Rautenberg
Hello Sven,
das blöde ist, dass es gar nicht funktioniert.
$gz = gzwrite() schreibt lt. Rückgabewert $gz immer nur sechs Bytes.
Auf der Platte hat der File 32 Bytes. Ohen gzwrite hat er 26. Also gehe ich mal davon aus, dass gzopen() den Dateivorspann davor schreibt und deshalb notwendig ist. Schön schlampig implementiert. Aber das wäre mir jetzt sogar noch egal, wenn es denn wengistens überhaupt tun würde. Was mach ich denn ggf. falsch?
Liebe Grüße aus http://www.braunschweig.de
Tom
Moin!
Was mach ich denn ggf. falsch?
"Dazu müßte man wissen, was du überhaupt machst, oder nicht?", murmelte er in seinen nichtvorhandenen Bart winkte drohend mit dem FAQ-Link. :)
- Sven Rautenberg
Hello,
"Dazu müßte man wissen, was du überhaupt machst, oder nicht?", murmelte er in seinen nichtvorhandenen Bart winkte drohend mit dem FAQ-Link. :)
Ja...
Die blödesten Fehler sind ja immer die, die man nicht vermutet. Also dann doch das Stück reduzierten Quellcode:
<?php ### gz_backup.php ###
$fp = fopen('news.dat','rb');
$buffer = fread($fp,filesize($dateiname));
$buf_len = strlen($buffer);
fclose($fp);
$fz = gzopen('news.dat.gz','wb');
$gz = gzwrite($fz, $buffer, strlen($buf_len));
gzclose($fz);
$gzstring = gzcompress ($buffer, 9);
$gz_len = strlen($gzstring);
$uzstring = gzuncompress($gzstring);
$uz_len = strlen($uzstring);
echo "<b>Bufferlänge:</b> $buf_len<br />";
echo "<b>GZ-Bufferlänge:</b> $gz_len<br />";
echo "<b>UZ-Bufferlänge:</b> $uz_len<br />";
echo "<b>komprimiert:</b> $gz<br />";
echo "habe fertig<br />";
?>
Liebe Grüße aus http://www.braunschweig.de
Tom
Hello,
$gzstring = gzcompress ($buffer, 9);
$gz_len = strlen($gzstring);
$uzstring = gzuncompress($gzstring);
$uz_len = strlen($uzstring);echo "<b>Bufferlänge:</b> $buf_len<br />";
echo "<b>GZ-Bufferlänge:</b> $gz_len<br />";
echo "<b>UZ-Bufferlänge:</b> $uz_len<br />";
jetzt hatte ich wieder etwas nervös schnell auf Submit gedrückt...
gzcompress() und gzuncompress() tun es aber.
Und da habe ich ein Ratio von ca. 32:1
Bufferlänge: 248887
GZ-Bufferlänge: 7589
UZ-Bufferlänge: 248887
Liebe Grüße aus http://www.braunschweig.de
Tom
Hello,
nochmal zu gz:
mit gzencode() kann ich auf dem System einen String komptimieren und in eine Datei packen. Die Datei ist dann mit einem "normalen" ZIP bzw. UnZIP-Programm auch lesbar, z.B. mit WinRAR. Das ist ja schon ganz zufriedenstellend.
Wie kann ich aber die Datei mittels gz-Funktion in PHP wieder entpacken? Das will und will nicht klappen!
Ich dachte nun, dass gzopen() und gzread() da helfen müssten, aber das war wohl nix. Oder sind die bei mir einfach buggy?
Liebe Grüße aus http://www.braunschweig.de
Tom
Liebe Grüße aus http://www.braunschweig.de
Tom
Hello,
Ja...
Die blödesten Fehler sind ja immer die, die man nicht vermutet. Also dann doch das Stück reduzierten Quellcode:
Nun hat sich das mal wieder bewahrheitet.
...
$buf_len = strlen($buffer);
...
$gz = gzwrite($fz, $buffer, strlen($buf_len));
------
So was bescheuertes...
Nun weiß ich wenigstens, dass ein Integer in PHP sech Bytes benötigt.
Dabei habe ich schon seit Tagen keinen Tropfen Allohol mehr getrunken. Aber vielleicht liegts ja am Tee.
Nun funktioniert es also so, wie es soll. Und immer noch enorm schnell. Da könnte man doch glatt die Flatfiles alle Zippen...
Liebe Grüße aus http://www.braunschweig.de
Tom
Moin!
Die blödesten Fehler sind ja immer die, die man nicht vermutet. Also dann doch das Stück reduzierten Quellcode:
Nun hat sich das mal wieder bewahrheitet.
...
$buf_len = strlen($buffer);
...
$gz = gzwrite($fz, $buffer, strlen($buf_len));
Das habe ich just in diesem Moment auch posten wollen.
Dumme Frage: Warum gibst du da überhaupt eine Länge an? Kostet doch nur Zeit (Aufruf der Funktion etc.), und nervt rum (wie man sieht).
- Sven Rautenberg
Hallo Sven,
Dumme Frage: Warum gibst du da überhaupt eine Länge an? Kostet doch
nur Zeit (Aufruf der Funktion etc.), und nervt rum (wie man sieht).
Spaetestens in der C-Version von gzwrite() wird die Laenge des Strings
eh ermittelt.
Grüße,
CK
Hello,
...
$buf_len = strlen($buffer);
...
$gz = gzwrite($fz, $buffer, strlen($buf_len));Das habe ich just in diesem Moment auch posten wollen.
Dumme Frage: Warum gibst du da überhaupt eine Länge an? Kostet doch nur Zeit (Aufruf der Funktion etc.), und nervt rum (wie man sieht).
Ja, da hast Du natürlich Recht. Zum Schreiben muss man sie ja nicht angeben, wenn der ganze Buffer verarbeitet wreden soll. Nur zum Lesen ist eine Länge notwendig und da steckte schon der nächste kleine Teufel versteckt, denn die Känge, siman bei gzread($fp,$len) angibt, ist die unkomprimierte, also wohl noch ein Relikt aus der Zeit, in der die Bufferlänge nicht dynamisch verwaltet wurde?
Muss man eben eine genügend große Zahl angeben. Irgendwo hatte ich auch ein Funktion gesehen, die die Größe der unkomprimierten Datei aus der komprimierten ermittelt, aber da gucke ich wohl schon wieder die ganze Zeit doof dran vorbei :-(
Liebe Grüße aus http://www.braunschweig.de
Tom
Hallo Tom,
Muss man eben eine genügend große Zahl angeben.
Nein. Im Regelfall wird das so gemacht:
define('BUFFLEN',512);
$gz = gzopen("file","r");
while(!gzeof($gz)) {
$str = gzread($gz,BUFFLEN);
# tu was mit $str
}
gzclose($gz);
Die Aktion in der Schleife kann selbstverstaendlich auch ein $str .=
sein. Die Groesse von 512 Byte habe ich gewaehlt, weil es bei vielen
x86-Systemen eine Groesse ist, die leicht alloziiert werden kann.
Grüße,
CK
Hello Christian,
Muss man eben eine genügend große Zahl angeben.
Nein. Im Regelfall wird das so gemacht:
define('BUFFLEN',512);
$gz = gzopen("file","r");
while(!gzeof($gz)) {
$str = gzread($gz,BUFFLEN);
# tu was mit $str
}
gzclose($gz);Die Aktion in der Schleife kann selbstverstaendlich auch ein $str .=
sein. Die Groesse von 512 Byte habe ich gewaehlt, weil es bei vielen
x86-Systemen eine Groesse ist, die leicht alloziiert werden kann.
...womit wir ja wieder beim Thema wären. Ich weiß ja, dass die Filezugriffe mehrfach buffered werden *hihi* aber gegen solche Konstruktionen sträubt sich mein altes Low-Level-Programmierer-Ego immer noch. Dass das so geht, war mir klar. Andersherum habe ich in meinem Scriptkonzept für diese Variable nur eine gewisse Größe vorgesehen und dann ist es ja nicht verkehrt, die auch zu achten. Der Leseprozess hört ja von alleine bei EOF auf, sonst wäre Deine Konstruktion auch nicht erlaubt.
Ergo kann man auch gleich eine entsprechende Anforderung stellen und hinterher vergleichen, wieviele Bytes gelesen werden konnten oder eben dann EOF abfragen.
Leider konnte ich in PHP 4 noch keine Möglichkeit entdecken, den für das Script noch verfügbaren Arbeitsspeicher bzw. den schon verwendeten zu ermitteln. Kennst Du eine?
Liebe Grüße aus http://www.braunschweig.de
Tom
Hallo Tom,
...womit wir ja wieder beim Thema wären. Ich weiß ja, dass die
Filezugriffe mehrfach buffered werden *hihi* aber gegen solche
Konstruktionen sträubt sich mein altes Low-Level-Programmierer-Ego
immer noch.
Du musst da was verwechseln. Dieser Algorithmus ist von mir von C
nach PHP portiert worden. Das ist die uebliche Vorgehensweise, wenn
man Dateien kopiert oder sequentiell filternt abarbeiten will, da
die performanteste Methode in Hinblick des Verhaeltnisses
Speicheraufwand und Systemcalls. Guck dir mal die Sourcen von cp oder
so an...
Leider konnte ich in PHP 4 noch keine Möglichkeit entdecken, den
für das Script noch verfügbaren Arbeitsspeicher bzw. den schon
verwendeten zu ermitteln. Kennst Du eine?
Es gibt keine.
Grüße,
CK
Hello,
Du musst da was verwechseln. Dieser Algorithmus ist von mir von C
nach PHP portiert worden. Das ist die uebliche Vorgehensweise, wenn
man Dateien kopiert oder sequentiell filternt abarbeiten will, da
die performanteste Methode in Hinblick des Verhaeltnisses
Speicheraufwand und Systemcalls. Guck dir mal die Sourcen von cp oder
so an...
"C" ist keinesfalls eine saubere und gut durchkonzipierte Sprache, sondern nur eine weit verbreitete Bastelkiste. Das sit absolut verglichbar mit der Qualität bestimmter weit verbreiteter Betriebssysteme. Beide strotzen nur so von Bugs und Denkfehlern, die ich, zugegeben, auch nicht beseitigen könnte, aber ab un zu begegnen sie mir eben.
Nur, weil dieser Algorithmus nun dort Verwendung findet, ist er noch lange nicht optimal.
Liebe Grüße aus http://www.braunschweig.de
Tom
Moin!
"C" ist keinesfalls eine saubere und gut durchkonzipierte Sprache, sondern nur eine weit verbreitete Bastelkiste.
Du verwechselst die Produkte des C-Obfuscation-Contest mit Algorithmen.
Das sit absolut verglichbar mit der Qualität bestimmter weit verbreiteter Betriebssysteme. Beide strotzen nur so von Bugs und Denkfehlern, die ich, zugegeben, auch nicht beseitigen könnte, aber ab un zu begegnen sie mir eben.
Und ab hier wirds einfach nur noch polemisch.
Nur, weil dieser Algorithmus nun dort Verwendung findet, ist er noch lange nicht optimal.
Wenn du einen besseren Algorithmus hast, dann her damit. Inkl. der Randbedingungen.
Bubblesort ist beispielsweise auch ein sehr schneller Sortieralgorithmus - bei Elementzahlen bis etwa zehn.
- Sven Rautenberg
Hello,
Und ab hier wirds einfach nur noch polemisch.
Das sehe ich nicht so.
Nur, weil dieser Algorithmus nun dort Verwendung findet, ist er noch lange nicht optimal.
Wenn du einen besseren Algorithmus hast, dann her damit. Inkl. der Randbedingungen.
Wenn man in Algorithmen innerhalb von Schleifen sehr teure Systemaufrufe verwendet, ist der Nutzen eben nicht so hoch, als wenn man sich einen Aufruf überlegt, der nur einmal teuer ist. Aber ich wollte das hier auch nicht diskutieren[1], denn das habe ich mit CK ja schon gemacht. Und bevor ich nicht weiß, was im Objektcode bzw. auf Assemblerebene passiert, kann ich sowieso nichts dazu sagen. Wogegen ich mich verwehrt habe ist allerdings die Aussage, weil es von cp portiert wurde, wäre es gut. So ahbe ich das jedenfalls verstanden und das unterschreibe ich nicht. Ich habe mich früher viel mit Netzwerkfähigen Programmen im Umfeld DOS-NOVELL herumgeschlagen und musste feststellen, dass das mit Pascal alles viel leichter und sauberer ging, als mit C. Die gleichen Macken, die in C damals schon drin waren, sind heute noch drin.
Man kann es zwar versuchen, aber total sytemunabhägig (entschichtet) kan man keine optimierten Programme schreiben. Dazu muss man auch heute noch immer wieder auf die Systemebene runter und da stellt man dann eben fest, dass viele Sachen da mehrmals hin und her gebogen werden.
Bubblesort ist beispielsweise auch ein sehr schneller Sortieralgorithmus - bei Elementzahlen bis etwa zehn.
Ein modifizierter Bubblesort ist übrigens einer der schnellsten Sortieralgorithmen, wenn man nicht genügend Arbeitsspeicher hat und auf das Auslagern auf einem Disklaufwerk angewiewsen ist *gg*
[1] Um die Dsikussion sinnvoll fortzusetzen, möchte ich erst die Zeit haben, mich mit den von CK neulich schon benannten Quellen des PHP Source Code auseinaderzusetzen. Ich gehe Euch aber (hoffentlich) noch nicht verloren und aufgeschoben ist nicht aufgehoben!
Liebe Grüße aus http://www.braunschweig.de
Tom
Hallo Tom,
Du musst da was verwechseln. Dieser Algorithmus ist von mir von C
nach PHP portiert worden. Das ist die uebliche Vorgehensweise,
wenn man Dateien kopiert oder sequentiell filternt abarbeiten
will, da die performanteste Methode in Hinblick des Verhaeltnisses
Speicheraufwand und Systemcalls. Guck dir mal die Sourcen von cp
oder so an..."C" ist keinesfalls eine saubere und gut durchkonzipierte Sprache,
sondern nur eine weit verbreitete Bastelkiste.
Nun, zunaechst einmal moechte ich dich bitten, das Bashing
einzustellen und mit Argumenten zu kommen. Wenn du schon auf C
schimpfen willst, dann bitte richtig und nicht mit stumpfen
nachgebrabbelten Saetzen.
Dann redest du von 'hardware-naher Programmierung', und damit kannst
du eigentlich nur C, Assembler oder direkt Maschinensprache
meinen -- in den anderen mir bekannten Sprachen kann man nicht
Hardware-nah programmieren.
Nur, weil dieser Algorithmus nun dort Verwendung findet, ist er
noch lange nicht optimal.
Das habe ich auch nicht gesagt. Bitte lies meine Postings
vollstaendig. Ich sagte, dieser Algorithmus ist deshalb die uebliche
Vorgehensweise, weil er den besten Kompromiss (die performanteste
Methode) in Hinblick auf Speicherverbrauch und Systemcalls darstellt.
So, und jetzt habe ich einfach keine Lust mehr, mit dir zu
diskutieren.
Grüße,
CK
Hello,
So, und jetzt habe ich einfach keine Lust mehr, mit dir zu
diskutieren.
Das muss auch nicht sein. Ich bereite mich außerdem ganz gerne auf eine solche Diskussion vor. Du warst ja wenigstens so fair, mir da ein paar Hinweise auf die Sources zu geben.
Mit Beißen hast DU übrigens angefangen und das schon vor Tagen. In diesem Punkte bin ich nachtragend, nicht aus menschlichen Erwägungen (jeder ist eben so wie er ist), sondern weil ich diesen Absulotismus in der Sache nicht mag.
Ich wünsche Dir aber trotzdem noch einen guten Tag und
liebe Grüße aus http://www.braunschweig.de
Tom
Sup!
"C" ist keinesfalls eine saubere und gut durchkonzipierte Sprache, sondern nur eine weit verbreitete Bastelkiste. Das sit absolut verglichbar mit der Qualität bestimmter weit verbreiteter Betriebssysteme. Beide strotzen nur so von Bugs und Denkfehlern, die ich, zugegeben, auch nicht beseitigen könnte, aber ab un zu begegnen sie mir eben.
Aha, wieder ein Anwärter auf die Mitgliedschaft bei den "Knights of the Lambda Calculus"?
Gruesse,
Bio
Moin!
Nun weiß ich wenigstens, dass ein Integer in PHP sech Bytes benötigt.
Nein. Deine Zahl hat 6 Stellen, die Stringlänge einer sechsstelligen Zahl ist 6.
Ich hatte eine Textdatei mit knapp 560 Zeichen. Ich schrieb "blablablablabla...". Und machte ein dummes Gesicht, als "zcat news.dat.gz" nur den Text "bla" ausgab. Nun gut, gzip komprimiert redundanz, aber SO STARK? :)
- Sven Rautenberg
Hallo Tom,
Nun weiß ich wenigstens, dass ein Integer in PHP sech Bytes
benötigt.
4 Byte. Integer in PHP sind 4 Byte gross.
Grüße,
CK
Hello,
Nun weiß ich wenigstens, dass ein Integer in PHP sech Bytes
benötigt.4 Byte. Integer in PHP sind 4 Byte gross.
hat Sven doch schon beirchtigt. Die Repräsentation der Zahl in "human readable" benötigt hier sechs Bytes. Aber das ist ja für dieses "Problem" genaus egal, weil es einfach die falsche Länge war. Doppelt hält eben nicht immer besser ;-)
Liebe Grüße aus http://www.braunschweig.de
Tom