Christian Seiler: Datei blockweise einlesen?

Beitrag lesen

Hallo Tom,

Frohes Neues Jahr.

Ebenso.

weil ich nämlich vergessen habe, wo dieser Default verdrahtet war und ob man ihn (ohne Neukompilation) ändern konnte oder nicht. Weißt Du das auswendig?

Ich hab mal kurz durch den Source geschaut (ich hab mal PHP 5.3.0 genommen, sollte aber für andere Versionen wie 5.2.x oder 5.3.1 ähnlich sein) und es scheint so, als ob stream->chunk_size für den Read-Buffer verantwortlich wäre, siehe

main/streams/streams.c:456:             chunk_buf = emalloc(stream->chunk_size);
main/streams/streams.c:466:                     justread = stream->ops->read(stream, chunk_buf, stream->chunk_size TSRMLS_CC);

Dann stellt sich die Frage, wie das gesetzt wird. Zum einen gibt's das Default:

main/streams/streams.c:245:     ret->chunk_size = FG(def_chunk_size);

Und das kommt daher:

ext/standard/file.c:174:  FG(def_chunk_size) = PHP_SOCK_CHUNK_SIZE;

Das ist definiert in:

main/php_network.h:200:#define PHP_SOCK_CHUNK_SIZE      8192

(Warum das PHP_SOCK_CHUNK_SIZE heißt, erschließt sich mir auch nicht... FG steht übrigens für "File Globals", halt also mal gar nichts mit Sockets zu tun. ;-))

Es gibt aber in der internen Streams-API eine Möglichkeit, das zu ändern, nämlich per php_stream_set_option. Die setzt das nämlich, siehe:

main/streams/streams.c:1182:                            stream->chunk_size = value;

Dummerweise wird die set_option-Funktion leider nicht exportiert (oder ich sehe gerade den Wald vor lauter Bäumen nicht), d.h. man kann die Puffergröße anscheinend nicht zur Laufzeit ändern... Das heißt: Doch neukompilieren oder zumindest C-Extension schreiben, die diese Funktion aufruft...

Was nebenbei noch interessant ist: Im PHP-Streams-Code gibt's auch noch eine Konstante CHUNK_SIZE, die ebenfalls auf 8192 gesetzt ist, die aber nichts mit der normalen Puffergröße zu tun hat. Die wird aber nur in _php_stream_copy_to_mem() verwendet, was u.a. von file_get_contents(), file(), getimagesize() im Falle von SWC-Bildern, stream_get_contents(), shell_exec() genutzt wird. In diesen Fällen ist das aber kein wirkliches Problem, weil das intern wieder auf php_stream_read (das mit stream->chunk_size) zurückfällt, was die eigentliche Leseoperation durchführt - mit einem größeren Puffer (und das, was hinterher nur im Speicher herumkopieren wird, ist auch bei Blöcken von nur 8 KiB noch verdammt schnell).

Viele Grüße,
Christian

--
Mein "Weblog" [RSS]
Using XSLT to create JSON output (Saxon-B 9.0 for Java)
»I don't believe you can call yourself a web developer until you've built an app that uses hyperlinks for deletion and have all your data deleted by a search bot.«
            -- Kommentar bei TDWTF