【问题标题】:fopen(file,w+) truncates the file before I can check if it's locked with flock()fopen(file,w+) 截断文件,然后我可以检查它是否被flock() 锁定
【发布时间】:2012-10-13 21:27:19
【问题描述】:

我有一个函数,它接收文件名和 json 对象以写入文本文件。

对象已更新,需要完全替换文件的当前内容。每个站点访问者都有自己的文件。多次快速更改会导致文件被fopen(file,w+) 截断,然后在锁定时不写入。最终结果是空文件。

我确信有一种标准的简单方法可以做到这一点,因为这是一种常见的活动。理想情况下,我正在寻找一种在w+ 模式下使用fopen 截断文件之前检查文件是否有锁的方法或切换模式的方法。

您必须使用fopen() 截断文件以获取文件句柄以传递给flock() 以检查它是否已锁定,这似乎很奇怪——但您只是截断了它,那有什么意义呢?

这是我目前拥有的功能:

function updateFile($filename, $jsonFileData) {
    $fp = fopen($filename,"w+");
    if (flock($fp, LOCK_EX)) {  
        fwrite($fp, $jsonFileData);
        flock($fp, LOCK_UN);
        fclose($fp);
        return true;
    } else {
        fclose($fp);
        return false;
    }
}

【问题讨论】:

  • 你为什么不为此使用数据库?
  • 从另一个接管项目,已经在处理文件。可以将其重新编码以使用数据库,但在重新设计之前尝试查看是否有其他解决方案。

标签: php fopen flock


【解决方案1】:

PHP manual 中的示例 #1 只需稍作修改即可满足您的需求。使用"c" mode打开文件进行写入,不存在就创建,不要截断。

$fp = fopen("/tmp/lock.txt", "c");

if (flock($fp, LOCK_EX)) {  // acquire an exclusive lock
    ftruncate($fp, 0);      // truncate file
    fwrite($fp, "Write something here\n");
    fflush($fp);            // flush output before releasing the lock
    flock($fp, LOCK_UN);    // release the lock
} else {
    echo "Couldn't get the lock!";
}

fclose($fp);

"c" mode的完整描述:

打开文件进行写入。如果文件不存在,则创建它。如果它存在,它既不会被截断(与“w”相反),对该函数的调用也不会失败(就像“x”一样)。文件指针位于文件的开头。如果希望在尝试修改文件之前获得建议锁(请参阅flock()),这可能很有用,因为使用 'w' 可能会在获得锁之前截断文件(如果需要截断,可以使用 ftruncate()在请求锁定后使用)。

看起来你不需要它,但如果你想读写,还有一个对应的"c+"模式。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多