原子创建文件的最佳方式

时间:2009-08-24 15:57:42

标签: php filesystems posix

以原子方式创建新文件的“最佳实践”(我认为)是打开一个临时文件(使用tmpfile()),然后将文件移动到它的最终位置。

但是,如果临时文件位于不同的挂载点上,这将无法正常工作,因为这会导致文件逐渐累积,并导致不必要的IO开销。

另一种选择是在与最终目的地相同的目录中创建临时文件,但这样做的缺点是为用户创建了一个不寻常的文件(像MS Word和ViM这样的应用程序会这样做,但我也认为这很糟糕行为)。

是否有与tmpfile()类似的方法允许我指定挂载点?我意识到这可能不存在内置的PHP,所以Posix / C函数或shell调用也是可以接受的。

4 个答案:

答案 0 :(得分:2)

不,POSIX堆栈中没有这样的方法。 tmpfile()和tmpname()用于普通临时目录。有tempnam(),您可以在其中指定临时文件的目标目录。但基本上是一种实现你所描述的第二种选择的方法。

答案 1 :(得分:1)

qmail开发的maildir协议为多个编写者提供了对同一目标目录的安全文件创建,甚至可以跨NFS。在此方案中,“tempfile”目录保证与目标目录位于同一文件系统上。

该算法可以方便地在高效的shell实用程序safecat中实现,其手册页将算法表示为:

  

safecat通过分六步编写数据来应用maildir算法。   首先,stat()是两个目录tempdir和destdir,然后退出   除非两个目录都存在且可写。其次,它是stat()的   name tempdir / time.pid.host,其中time是自之后的秒数   1970年初GMT,pid是程序的进程ID,而主机是   主机名。第三,如果stat()返回ENOENT以外的任何内容,   程序休眠两秒钟,更新时间,并尝试stat()   再次,有限次数。第四,该计划创造   TEMPDIR / time.pid.host。第五,程序NFS将消息写入   文件。第六,程序link()将文件发送到destdir / time.pid.host。在   那个数据已成功写入的瞬间。

     

此外,safecat在创建之前启动24小时计时器   tempdir / time.pid.host,如果计时器到期则中止写入。上   错误,超时或正常完成,safecat尝试取消链接()   TEMPDIR / time.pid.host。

答案 2 :(得分:0)

当你在谈论“mountpoint”时,我假设你处于类似unix的环境中。

也许您可以将其视为变通方法或不良行为,但我认为在同一目标文件夹上创建隐藏(.tmpfile)临时文件是可以接受的。

您当然可以在适合此任务的应用程序无法访问的同一安装点上创建特定文件夹,如果您不希望在同一个安装点上模拟tempfile(),如果您不希望看到任何虚假文件目的地目录。

答案 3 :(得分:-1)

我必须做这样的事情并使用MySQL DB。只是在表格中存储了我需要的信息,当我完成时我刚刚删除了记录。只是一个想法:)