php - unlink throws error: Resource temporarily unavailable

php - unlink throws error: Resource temporarily unavailable

这是一段代码:

public function uploadPhoto(){
    $filename = '../storage/temp/image.jpg';  
    file_put_contents($filename,file_get_contents('http://example.com/image.jpg'));
    $photoService->uploadPhoto($filename);
    echo("If file exists: ".file_exists($filename));
    unlink($filename);
}

我正在尝试做以下事情:

  1. 从 URL 获取照片并将其保存在我服务器的临时文件夹中。这很好用。图像文件已创建并在 echo("If file exists: ".file_exists('../storage/temp/image.jpg'));.
  2. 时回显 If file exists: 1
  3. 将该文件传递给另一个处理将文件上传到 Amazon s3 存储桶的函数。该文件存储在我的 s3 存储桶中。
  4. 删除存储在临时文件夹中的照片。 这不起作用! 我收到一条错误消息:

unlink(../storage/temp/image.jpg): Resource temporarily unavailable

如果我使用 rename($filename,'../storage/temp/renimage.jpg'); 而不是 unlink($filename); 我会得到一个错误:

rename(../storage/temp/image.jpg,../storage/temp/renimage.jpg): The process cannot access the file because it is being used by another process. (code: 32)

如果我删除函数调用 $photoService->uploadPhoto($filename);,一切正常。

如果文件正在被另一个进程使用,在进程完成并且文件不再被任何进程使用后,如何取消链接?我不想使用定时器。

请帮忙!提前致谢。

unlink 方法 return 布尔值,因此您可以构建一个循环,使用一些 wait() 和重试限制来等待您的进程完成。

另外在取消链接上加上“@”,以隐藏访问错误。

如果达到重试次数,则抛出另一个 error/exception。

刚刚不得不处理类似的错误。

您的 $photoService 似乎出于某种原因保留了图片... 由于您没有共享 $photoService 的代码,我的建议是做这样的事情(假设您不再需要 $photoService):

[...]
echo("If file exists: ".file_exists($filename));
unset($photoService);
unlink($filename);
}

unset() 方法将破坏给定的 variable/object,因此它不能 "use"(或无论它做什么)任何文件。

我遇到了同样的问题。在执行取消链接之前,S3 客户端似乎不想解锁。如果将内容提取到变量中并将其设置为 putObject 数组中的 'body':

$fileContent = file_get_contents($filepath);
$result = $s3->putObject(array(
    'Bucket'       => $bucket,
    'Key'          => $folderPath,
    'Body'         => $fileContent,
     //'SourceFile'   => $filepath,
    'ContentType'  => 'text/csv',
    'ACL'          => 'public-read'
));

看到这个答案:

我在这个问题上坐了一两个小时,终于意识到 "temporarily unavailable" 真的意味着 "temporarily"。

在我的例子中,并发 PHP 脚本访问文件,写入或读取。当 unlink() 过程的时机不佳时,整个过程就失败了。

解决方案非常简单:使用(通常不太可取)@ 来防止向用户显示错误(当然,也可以阻止 beinf 打印错误),然后使用另一个尝试:

$gone = false;
for ($trial=0; $trial<10; $trial++) {
    if ($gone = @unlink($filename)) {
        break;
    }
    // Wait a short time
    usleep(250000);
    // Maybe a concurrent script has deleted the file in the meantime
    clearstatcache();
    if (!file_exists($filename)) {
        $gone = true;
        break;
    }
}
if (!$gone) {
    trigger_error('Warning: Could not delete file '.htmlspecialchars($filename), E_USER_WARNING);
}

在解决这个问题并进一步推动我的运气之后,我还可以用 file_put_contents() 触发 "Resource temporarily unavailable" 问题。同样的解决方案,现在一切正常。

如果我足够聪明and/or以后取消链接失败,我会把@替换成ob_start(),所以错误信息可以告诉我确切的错误。

最简单的解决方案:

gc_collect_cycles();
unlink($file);

适合我吗! 将文件上传到 amazon S3 后,它允许我删除服务器上的文件。

看这里:https://github.com/aws/aws-sdk-php/issues/841

The GuzzleHttp\Stream object holds onto a resource handle until its __destruct method is called. Normally, this means that resources are freed as soon as a stream falls out of scope, but sometimes, depending on the PHP version and whether a script has yet filled the garbage collector's buffer, garbage collection can be deferred. gc_collect_cycles will force the collector to run and call __destruct on all unreachable stream objects.

:)