stream_set_write_buffer
(PHP 4 >= 4.3.0, PHP 5)
stream_set_write_buffer — Устанавливает буферизацию файла при записи в указанный поток
Описание
$stream
, int $buffer
)
Устанавливает буферизацию для операций записи на заданном потоке stream
в число buffer
байт.
Вывод с использованием функции fwrite() обычно буферизуется по 8 килобайт. Это означает, что если два процесса хотят записывать данные в один и тот же поток вывода (файл), каждый будет останавливаться после 8 килобайт данных для того, чтобы позволить записать данные другому.
Список параметров
-
stream
-
Файловый указатель.
-
buffer
-
Число байт для буферизации. Если аргумент
buffer
равен 0, то операции записи не буферизуются. Это гарантирует, что все операции записи с использованием функции fwrite() будут завершены перед тем, как другим процессам будет позволено записывать в поток вывода.
Возвращаемые значения
Возвращает 0 в случае успеха, или EOF в случае, если запрос не может быть выполнен.
Примеры
Пример #1 Пример использования stream_set_write_buffer()
Следующий пример демонстрирует использование функции stream_set_write_buffer() для создания небуферизуемого потока.
<?php
$fp = fopen($file, "w");
if ($fp) {
stream_set_write_buffer($fp, 0);
fwrite($fp, $output);
fclose($fp);
}
?>
- PHP Руководство
- Функции по категориям
- Индекс функций
- Справочник функций
- Другие базовые расширения
- Потоки
- set_socket_blocking
- stream_bucket_append
- stream_bucket_make_writeable
- stream_bucket_new
- stream_bucket_prepend
- stream_context_create
- stream_context_get_default
- stream_context_get_options
- stream_context_get_params
- stream_context_set_default
- stream_context_set_option
- stream_context_set_params
- stream_copy_to_stream
- stream_encoding
- stream_filter_append
- stream_filter_prepend
- stream_filter_register
- stream_filter_remove
- stream_get_contents
- stream_get_filters
- stream_get_line
- stream_get_meta_data
- stream_get_transports
- stream_get_wrappers
- stream_is_local
- stream_notification_callback
- stream_register_wrapper
- stream_resolve_include_path
- stream_select
- stream_set_blocking
- stream_set_chunk_size
- stream_set_read_buffer
- stream_set_timeout
- stream_set_write_buffer
- stream_socket_accept
- stream_socket_client
- stream_socket_enable_crypto
- stream_socket_get_name
- stream_socket_pair
- stream_socket_recvfrom
- stream_socket_sendto
- stream_socket_server
- stream_socket_shutdown
- stream_supports_lock
- stream_wrapper_register
- stream_wrapper_restore
- stream_wrapper_unregister
Коментарии
Trying to use stream_set_write_buffer on a local file will always fail according to this note from 2003.
http://grokbase.com/t/php/php-internals/0351gp6xtn/stream-set-write-buffer-does-not-work
Example:
$fp = fopen("localfile.txt", "w");
if (stream_set_write_buffer($fp, 0) !== 0) {
// changing the buffering failed is always true on local files
}
The stream_set_write_buffer() function has been broken since PHP 4.3.0. As a workaround, I would suggest using a php_user_filter as an output buffer. By using the following class I have measured over 50% performance improvements with scripts that generate large text files by writing them one line at a time:
class my_output_buffer extends php_user_filter
{
protected static $BUFFER_SIZE = 4096;
function onCreate( ) {
$this->bff = [];
$this->len = 0;
return true;
}
public function filter($in, $out, &$consumed, $closing)
{
$rv = PSFS_FEED_ME; /* assume no output */
/* process input */
while ($bucket = stream_bucket_make_writeable($in)) {
/* bucket is too big for the buffer? */
$space = static::$BUFFER_SIZE - $this->len;
if ($bucket->datalen >= $space) {
/* consume data by placing it into internal buffers */
$this->bff[] = substr($bucket->data, 0, $space);
$this->len += $space;
$overflow = substr($bucket->data, $space);
$ovfl_len = $bucket->datalen - $space;
$consumed += $bucket->datalen;
assert($this->len == static::$BUFFER_SIZE);
/* make one big bucket */
$bucket->data = implode('', $this->bff);
$bucket->datalen = static::$BUFFER_SIZE;
stream_bucket_append($out, $bucket);
$rv = PSFS_PASS_ON; /* we have output! */
/* handle overflow */
$this->bff = [$overflow];
$this->len = $ovfl_len;
}
else {
/* consume data by placing it into internal buffers */
$this->bff[] = $bucket->data;
$this->len += $bucket->datalen;
$consumed += $bucket->datalen;
}
}
/* stream is closing and we have data? */
if ($closing && $this->len > 0) {
/* make one last bucket */
$data = implode('', $this->bff);
$bucket = stream_bucket_new($this->stream, $data);
stream_bucket_append($out, $bucket);
$rv = PSFS_PASS_ON; /* we have output! */
/* clear internal buffer */
$this->bff = [];
$this->len = 0;
}
return $rv;
}
}
$fp = fopen('foobar.txt', 'w');
/* enable filtering */
stream_filter_register('output.buffer', 'my_output_buffer');
stream_filter_append($fp, 'output.buffer');
/* a lot of small writes */
for ($i = 0; $i < 10000; $i++) {
fwrite($fp, 'x');
}
fclose($fp);