Php 执行Imagick writeImage()时锁定文件

Php 执行Imagick writeImage()时锁定文件,php,imagick,Php,Imagick,是否可以锁定文件img.jpg,直到Imagick创建它 $image->writeImage('img.jpg') 我不完全确定你所描述的问题是否真的存在。没有其他人报告过此事 然而,即使这是一个问题,您也不希望在这里使用文件锁定……这是为了解决一组单独的问题 相反,你想使用的是原子操作,由计算机“瞬间”完成 $created = false; for ($i=0; $i<5 && $created == false; $i++) { // Create

是否可以锁定文件img.jpg,直到Imagick创建它

$image->writeImage('img.jpg')

我不完全确定你所描述的问题是否真的存在。没有其他人报告过此事

然而,即使这是一个问题,您也不希望在这里使用文件锁定……这是为了解决一组单独的问题

相反,你想使用的是原子操作,由计算机“瞬间”完成

$created = false;
for ($i=0; $i<5 && $created == false; $i++) {
    // Create a temp name
    $tmpName = "temp".rand(10000000, 99999999).".jpg";

    // Open it. The x+ means 'do not create if file already exists'.
    $fileHandle = @fopen($tmpName, 'x+');
    if ($fileHandle === false) {
        // The file with $tmpName already exists, or we otherwise failed
        // to create the file, loop again.
        continue;
    }
    // We don't actually want the file-handle, we just wanted to make sure 
    // we had a uniquely named file ending with .jpg so just close it again.
    // You could also use tempnam() if you don't care about the file extension.
    fclose($fileHandle);
    // Writes the image data to the temp file name.
    $image->writeImage($tmpName);
    rename($tmpName, 'img.jpg');
    $created = true;
}

if ($created === false) {
    throw new FailedToGenerateImageException("blah blah");
}
$created=false;
对于($i=0;$iwriteImage($tmpName);
重命名($tmpName,'img.jpg');
$created=true;
}
如果($created==false){
抛出新的FailedGenerateImageException(“废话”);
}

这里没有锁定…但是任何进程都不可能在写入img.jpg时从img.jpg中读取数据。如果在重命名过程中有任何其他进程具有img.jpg,则它们对文件旧版本的文件句柄将继续存在,并且它们将继续读取旧文件,直到它们关闭并运行请再写一次。

我不完全确定您描述的问题是否确实存在。没有其他人报告过

然而,即使这是一个问题,您也不希望在这里使用文件锁定……这是为了解决一组单独的问题

相反,你想使用的是原子操作,由计算机“瞬间”完成

$created = false;
for ($i=0; $i<5 && $created == false; $i++) {
    // Create a temp name
    $tmpName = "temp".rand(10000000, 99999999).".jpg";

    // Open it. The x+ means 'do not create if file already exists'.
    $fileHandle = @fopen($tmpName, 'x+');
    if ($fileHandle === false) {
        // The file with $tmpName already exists, or we otherwise failed
        // to create the file, loop again.
        continue;
    }
    // We don't actually want the file-handle, we just wanted to make sure 
    // we had a uniquely named file ending with .jpg so just close it again.
    // You could also use tempnam() if you don't care about the file extension.
    fclose($fileHandle);
    // Writes the image data to the temp file name.
    $image->writeImage($tmpName);
    rename($tmpName, 'img.jpg');
    $created = true;
}

if ($created === false) {
    throw new FailedToGenerateImageException("blah blah");
}
$created=false;
对于($i=0;$iwriteImage($tmpName);
重命名($tmpName,'img.jpg');
$created=true;
}
如果($created==false){
抛出新的FailedGenerateImageException(“废话”);
}

这里没有锁定…但是任何进程都不可能在写入img.jpg时从img.jpg中读取数据。如果在重命名过程中有任何其他进程具有img.jpg,则它们对文件旧版本的文件句柄将继续存在,并且它们将继续读取旧文件,直到它们关闭并运行再次书写。

你能说出为什么要这样做吗。我可以试着想象为什么,但如果用例更清楚,回答你的问题会更容易。@Danack当用户试图获取这个文件时,它已经存在,但尚未完全创建,用户得到了损坏的文件。你看到了吗?ImageMagick应该使用atomic文件操作…你能说说为什么要这样做吗。我可以试着想象为什么,但如果用例更清楚,回答你的问题会更容易。@Danack当用户试图获取这个文件时,它已经存在,但还没有完全创建,用户会断开文件你看到了吗?ImageMagick应该使用原子文件操作。。。