Intereting Posts
Сделать сценарий неудачным путем сериализации Closure nusoap XML-анализ ошибок WSDL Удалить ребенка с определенным атрибутом, в SimpleXML для PHP Как предотвратить загрузку страницы моего сайта через сторонний фрейм сайта iFrame Отправка формы с помощью jQuery / Ajax работает только в другое время Шрифт Bootstrap glyphicons font не найден при использовании assetic в prod на Symfony2 Получение данных GET и POST внутри контроллера в Laravel 4 Автоматическое обновление этого столбца после 24:00 (0.00 AM) с помощью PHP? Есть ли у PHP ответ на универсальные классы стиля Java? Удалить числовой префикс из строки – PHP regex Можно ли указать динамический тип, возвращаемый в PhpStorm? Laravel для многих моделей, связанных с загрузкой, с подсчетом изменить путь PHP к MAMPs PHP Как я могу удалить данные: часть изображения из строки base64 любого типа изображения в PHP Как быстро выбрать 3 случайные записи из таблицы 30k MySQL с фильтром где-то одним запросом?

PHP: fseek () для большого файла (> 2 ГБ)

У меня очень большой файл (около 20 ГБ), как я могу использовать fseek (), чтобы прыгать и читать его содержимое.

Код выглядит так:

function read_bytes($f, $offset, $length) { fseek($f, $offset); return fread($f, $length); } 

Результат будет правильным, если $ offset <2147483647.

Обновление: я запускаю на windows 64, phpinfo – Архитектура: x64, PHP_INT_MAX: 2147483647

для моего проекта мне нужно было выполнить READ блоки 10KB с BIG offset в BIG-файле (> 3 ГБ). Писания всегда добавлялись, поэтому никаких смещений не требовалось.

это будет работать, независимо от того, какую версию PHP и ОС вы используете.

Предпосылка = сервер должен поддерживать запросы поиска по диапазону. Apache и IIS уже поддерживают это, так же как 99% других веб-серверов (общий хостинг или иначе)

 // offset, 3GB+ $start=floatval(3355902253); // bytes to read, 100 KB $len=floatval(100*1024); // set up the http byte range headers $opts = array('http'=>array('method'=>'GET','header'=>"Range: bytes=$start-".($start+$len-1))); $context = stream_context_create($opts); // bytes ranges header print_r($opts); // change the URL below to the URL of your file. DO NOT change it to a file path. // you MUST use a http:// URL for your file for a http request to work // this will output the results echo $result = file_get_contents('http://127.0.0.1/dir/mydbfile.dat', false, $context); // status of your request // if this is empty, means http request didnt fire. print_r($http_response_header); // Check your file URL and verify by going directly to your file URL from a web // browser. If http response shows errors ie code > 400 check you are sending the // correct Range headers bytes. For eg - if you give a start Range which exceeds the // current file size, it will give 406. // NOTE - The current file size is also returned back in the http response header // Content-Range: bytes 355902253-355903252/355904253, the last number is the file size ... 

SECURITY – вы должны добавить правило .htaccess, которое отклоняет все запросы для этого файла базы данных, кроме тех, которые поступают из локального ip 127.0.0.1.

ПРЕДУПРЕЖДЕНИЕ: как отмечено в комментариях, fseek использует INT внутри себя, и он просто не может работать с такими большими файлами в 32-битных компиляциях PHP. Следующее решение не будет работать. Он оставлен здесь только для справки.

немного поиска привело меня к комментариям на странице руководства PHP для fseek:

http://php.net/manual/en/function.fseek.php

проблема заключается в максимальном размере int для параметра offset, но кажется, что вы можете обойти его, выполнив несколько вызовов fseek с помощью опции SEEK_CUR и смешав их с одной из библиотек обработки больших чисел.

пример:

 function fseek64(&$fh, $offset) { fseek($fh, 0, SEEK_SET); $t_offset = '' . PHP_INT_MAX; while (gmp_cmp($offset, $t_offset) == 1) { $offset = gmp_sub($offset, $t_offset); fseek($fh, gmp_intval($t_offset), SEEK_CUR); } return fseek($fh, gmp_intval($offset), SEEK_CUR); } fseek64($f, '23456781232');