php - PHP:我可以使用内置的 curl 函数通过 gunzip 管道 curl 输出吗?
问题描述
我正在编写一个脚本,该脚本下载大文件,解压缩它们,然后解析内容,将我喜欢的数据插入到 sql 中。我将此脚本升级为以多线程类型的方式工作,它可以同时下载一个文件、解压缩另一个文件并解析另一个文件。但是,唉,我遇到了硬盘驱动器的瓶颈。
在 的帮助下##php
,我意识到我可以使用以下命令将输出curl
直接通过管道传输gunzip
到将我的磁盘 i/o 减半(不包括 SQL):
卷曲https://example.com/path/to/large_file.gz | gunzip -c > /large_temp_files/large_file
经测试证实,该方法将未压缩的数据直接写入磁盘,无需先写入压缩数据。
所以我的问题是,有什么方法可以像使用 php 的内置curl
函数那样管道数据?
对于常规文件,您可以打开文件指针并将该指针设置为curl_setopt
选项之一,以将文件下载到磁盘而不是将数据设置为变量。
这些是 5 GB 的文件,因此无法正常工作。我的所有其他代码都为我的 http 请求使用内置函数,所以如果可能的话,我想坚持这样做,以保持一致性和可读性。
解决方案
我实际上并没有对此进行测试,但我认为这可以通过使用带有 inflate_init() 和 co 的自定义 CURLOPT_WRITEFUNCTION 来实现,例如
$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 数据库中,而无需将解压缩的数据写入磁盘,这可能更快(与从硬盘驱动器读取相比,从 ram 读取非常快 :) )
推荐阅读
- node.js - 保护 AWS S3 下载链接
- javascript - 在为动态内容加载文档后尝试手动调用 MathJax 时出现“ReferenceError:MathJax 未定义”
- c - 如何找到大数的二进制表示?
- java - LinkOption.NOFOLLOW_LINKS 的含义是什么以及何时使用它?
- javascript - 试图切换 dd 元素的可见性
- javascript - 类中的 PHP 函数返回空值
- html - alt="" 在技术上不可行的空 alt 属性的最佳实践
- excel - 如果单元格字符串包含列中列表中的单词,则将值返回到新单元格
- json - 从 http.get 解组嵌套的 json
- c# - 在包含所述接口类型成员的类上定义接口类型的正确方法