Прочитать локальный файл с установленным timeout на операцию

Cude2

Новичок
Привет!

Нужно прочитать локальный файл с медленного диска. Причем надо контролировать время затраченное на это, и если оно превышено, прекращать это занятие. Чтение файла по частям не подходит, начинаются проблемы с производительностью (читать надо много файлов, общим объемом много-много гигабайт)
 

Cude2

Новичок
@Cude2,
https://secure.php.net/manual/ru/class.streamwrapper.php
В stream_read контролируем время чтения.
Уже читал, написано что "Это НЕ реальный класс, а лишь прототип, предоставленный в качестве наглядного пособия."
Либо я не понял как его использовать.

вроде бы можно сделать что-то похожее, но с локальными файлами, stream_set_timeout возвращает false:
$fh = fopen(...);
stream_set_timeout($fh, 1);

А он так и так будет читаться по частям.
Мне все равно как он внутри себя будет читать. Главное чтобы мне не пришлось объединять прочитанные части файла в одну строку (именно это кладет php на колени)
 

MiksIr

miksir@home:~$
Главное чтобы мне не пришлось объединять прочитанные части файла в одну строку (именно это кладет php на колени)
Склеивай строки не так $s = $s.$s1; а так $s .= $s1; и все будет хорошо. В первом случае у тебя двойной расход памяти будет.

Т.е. можете спокойно читать 4096 блоками обычным fread засекая таймер на каждое чтение.
 
Последнее редактирование:

fixxxer

К.О.
Партнер клуба
@Cude2,
https://secure.php.net/manual/ru/class.streamwrapper.php
В stream_read контролируем время чтения.
Это не сработает для локальной ФС (или я отстал от жизни?)
Можно это сделать через select() с таймаутом, например.

Но вообще, да, читать надо по частям, кусками, кратными размеру чанка в файловой системе.
 

Cude2

Новичок
Склеивай строки не так $s = $s.$s1; а так $s .= $s1; и все будет хорошо. В первом случае у тебя двойной расход памяти будет.
У меня итак .= используется

Это не сработает для локальной ФС (или я отстал от жизни?)
Можно это сделать через select() с таймаутом, например.
Напишите пример если не сложно, я не представляю как это сделать.
Особенно не понимаю как streamwrapper использовать, ведь он и так используется при вызове fopen, fread итд. И там вызов stream_set_timeout никак не помогает.
 

fixxxer

К.О.
Партнер клуба
Напишите пример если не сложно, я не представляю как это сделать.
Я, если честно, не уверен, что это сработает (может и полочиться), но, по идее, как-то так:
PHP:
$fh = fopen($filename, 'r');
$read = [$fh];
$write = null;
$err = null;
$s = '';
while (!feof($fh)) {
    $res = stream_select($read, $write, $err, 1);
    if ($res === false) {
        throw new \Exception('Read timeout');
    }
    if ($res) {
        $s .= fread($fh, 512);
    }
}

echo $s;
 

Cude2

Новичок
Я, если честно, не уверен, что это сработает (может и полочиться), но, по идее, как-то так:
PHP:
$fh = fopen($filename, 'r');
$read = [$fh];
$write = null;
$err = null;
$s = '';
while (!feof($fh)) {
    $res = stream_select($read, $write, $err, 1);
    if ($res === false) {
        throw new \Exception('Read timeout');
    }
    if ($res) {
        $s .= fread($fh, 512);
    }
}

echo $s;
Работает, но время не учитывает (
 

fixxxer

К.О.
Партнер клуба
А, выыыыньдовс. Там не знаю как, наверное, только тредом отдельным.
 
Сверху