PHP: Могу ли я передать вывод curl через gunzip, используя встроенные функции curl? - PullRequest
1 голос
/ 18 апреля 2019

Я работаю над сценарием, который загружает большие файлы, распаковывает их, а затем анализирует содержимое, вставляя данные, которые мне нравятся, в sql. Я обновил этот сценарий, чтобы он работал в многопоточном режиме, где он загружает один файл, распаковывает другой файл и одновременно анализирует другой файл. Но, увы, я становлюсь узким местом на жестком диске.

С помощью ##php я понял, что могу использовать следующую команду, чтобы направить вывод curl непосредственно в gunzip, чтобы сократить мой дисковый ввод-вывод пополам (исключая SQL):

завиток https://example.com/path/to/large_file.gz | gunzip -c> / large_temp_files / large_file

Протестировано и подтверждено, этот метод записывает несжатые данные непосредственно на диск без предварительной записи сжатых данных.

Итак, мой вопрос: есть ли способ, как я могу передать данные таким образом, используя встроенную в php функцию curl?

Для обычных файлов вы можете открыть указатель файла и установить этот указатель в качестве одного из параметров curl_setopt, чтобы загрузить файл на диск, а не задавать данные переменной.

Это файлы размером 5 ГБ, поэтому они не будут работать. Весь мой другой код использует встроенные функции для моих http-запросов, поэтому я хотел бы придерживаться этого, если это возможно, для согласованности и удобочитаемости.

1 Ответ

1 голос
/ 21 апреля 2019

Я на самом деле не проверял это, но я предполагаю, что это возможно при использовании пользовательского CURLOPT_WRITEFUNCTION с inflate_init () & co, что-то вроде

$decompressor = inflate_init(ZLIB_ENCODING_DEFLATE);
$fp = fopen("decompressed", "wb");
$ch = curl_init("http://url.com/large_file.zip");
curl_setopt_array($ch, array(
    CURLOPT_WRITEFUNCTION => function ($ch, string $compressed) use (&$fp, &$decompressor) {
        fwrite($fp, inflate_add($decompressor, $compressed));
        return strlen($compressed);
    }
));
curl_exec($ch);
curl_close($ch);
fclose($fp);
unset($fp,$ch,$decompressor); // don't know how to clean up the decompressor, hopefully GC will do it.

кстати, если вы хотите по-настоящему модно, вывозможно, можно было бы проанализировать данные непосредственно из вызова deflate_add () и вставить их в базу данных SQL, даже не записывая распакованные данные на диск, что может быть даже быстрее (по сравнению с чтением с жесткого диска чтение из оперативной памяти равно ОЧЕНЬ быстро :))

...