Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Google云存储获取临时文件名(使用fopen(';php://temp'))_Php_Google Cloud Storage_Guzzle_Guzzle6 - Fatal编程技术网

Google云存储获取临时文件名(使用fopen(';php://temp'))

Google云存储获取临时文件名(使用fopen(';php://temp')),php,google-cloud-storage,guzzle,guzzle6,Php,Google Cloud Storage,Guzzle,Guzzle6,几年前这里也有类似的问题,但没有答案: 我正在使用谷歌云存储并行下载大量大型文件,然后将它们上传到另一个服务。基本上是通过我的服务器B从A传输到C 在后台,谷歌的->downloadstream()使用Guzzle通过fopen()获取文件php://temp“,”r+”) 我遇到了磁盘空间问题,因为如果在传输过程中出现异常,谷歌的云存储库不会清理临时文件。(这是根据的预期行为)。每次重试脚本都会在我的tmp目录中转储另一个未清理的大文件 如果Guzzle使用tmpfile()我将能够使用st

几年前这里也有类似的问题,但没有答案:

我正在使用谷歌云存储并行下载大量大型文件,然后将它们上传到另一个服务。基本上是通过我的服务器B从A传输到C

在后台,谷歌的->
downloadstream()
使用Guzzle通过
fopen()获取文件php://temp“,”r+”)

我遇到了磁盘空间问题,因为如果在传输过程中出现异常,谷歌的云存储库不会清理临时文件。(这是根据的预期行为)。每次重试脚本都会在我的tmp目录中转储另一个未清理的大文件

如果Guzzle使用
tmpfile()
我将能够使用
stream\u get\u meta\u data()['uri']
获取文件路径,但因为它使用
php://temp
,此选项似乎已被禁用:

[
 "wrapper_type" => "PHP",
 "stream_type" => "TEMP",
 "mode" => "w+b",
 "unread_bytes" => 0,
 "seekable" => true,
 "uri" => "php://temp", // <<<<<<<< grr.
]
更新2


这是可能的,请参阅下面接受的答案。

它很可能是您可以通过的系统配置的临时目录

请注意,这将仅在需要时保存到文件,并且可以驻留在内存中。


编辑:确定,创建的文件。然后您可能可以使用流句柄从流中获取信息。

谷歌云平台支持

目前,使用php云存储库无法获得在使用方法downloadstream()时创建的临时文件名。因此,我代表您创建了一个功能请求,您可以按照它进行操作

作为一种解决方法,您可以手动删除该文件,您可以使用以下命令获取临时文件名:

$filename = shell_exec('ls -lt | awk 'NR==2' | cut -d: -f2 | cut -d " " -f2');
在此之后,$filename将包含上次修改的文件名,该文件名将是失败的文件名,您希望删除该文件名。使用文件名,您现在可以继续删除它


请注意,您必须在您的php://temp 执行函数之前,请先打开文件夹。

类似于以下内容的操作应该可以实现此目的:

use Google\Cloud\Storage\StorageClient;

$client = new StorageClient;

$tempStream = tmpfile();
$tempFile = stream_get_meta_data($tempStream)['uri'];

try {
    $stream = $client->bucket('my-bucket')
        ->object('my-big-ol-file')
        ->downloadAsStream([
            'restOptions' => [
                'sink' => $tempStream
            ]
        ]);
} catch (\Exception $ex) {
    unlink($tempFile);
}

restOptions
选项允许您通过命令代理底层HTTP 1.1传输(默认情况下为Guzzle)。我很抱歉,这没有明确的记录,但希望能有所帮助

谢谢,是的,它将进入
sys\u get\u temp\u dir()
(在我的例子中是/tmp),但它是我要查找的文件名。例如
/tmp/php89089809
。是的,文件太大,内存太大,所以被放在磁盘上。@lufc Ahhh好的。。。用相关信息更新了答案。在我的问题的底部,你可以看到
stream\u get\u meta\u data
的输出,以及为什么不起作用:)啊,对不起。。。长途开车后我太累了。这就是“应该”给你的。不知道为什么没有。您可以强制执行一个解决方案,并获得拥有php进程的用户所拥有的tempfolder中的文件列表,然后进行比较以查找添加的文件。但它并不像实际获取特定文件的路径那样优雅:PAlso,在Guzzle中,您可以设置保存文件的文件名。难道你没有权限访问它,并且可以使用它,这样你在设置它之后就知道它的名字了吗?谢谢@bhito。如果这被添加到库中,请更新答案。我会关注它,并在我得到更新后立即通知你!你能找到解决办法吗@lufcYes,请参阅上面的更新。这没关系,但显然没有它可能的那么有效。哇,我想你是对的-看起来这被隐藏在
buildDownloadObjectParams()
这里:和
getRequestOptions()
这里:(我将在生成下一个大文件并准备好下载后尝试,然后报告/接受答案)@lufc这有帮助吗?是的!非常感谢。实际上,我使用
tempnam()
my big ol file
作为前缀设置一个名称,然后使用它。这样,当传输大量文件时,我可以监视tmp目录,查看正在下载的内容等。
use Google\Cloud\Storage\StorageClient;

$client = new StorageClient;

$tempStream = tmpfile();
$tempFile = stream_get_meta_data($tempStream)['uri'];

try {
    $stream = $client->bucket('my-bucket')
        ->object('my-big-ol-file')
        ->downloadAsStream([
            'restOptions' => [
                'sink' => $tempStream
            ]
        ]);
} catch (\Exception $ex) {
    unlink($tempFile);
}