找出fopen(...,' a')是否创建了一个新文件

时间:2015-07-09 08:36:49

标签: php

在我的PHP项目中,我使用某种类型的计数器经常附加到现有(或新)文件:

$f = fopen($filename, 'ab');
fwrite($f);
fclose($f);

创建新文件时,我必须编辑此文件的权限,以便其他用户也可以访问该文件:

$existed = file_exists($filename);
// Do the append
$f = fopen($filename, 'ab');
fwrite($f);
fclose($f);
// Update permissions
if (!$existed) {
    @chmod($filename, 0666);
}

有没有办法找出,是否' a' (append)在不使用file_exists()的情况下创建了一个新文件或附加到现有文件?据我所知,file_exists()检索文件统计信息,与简单的文件追加相比,这会导致一些不必要的开销。由于该功能经常使用,我想知道是否可以选择在不使用fopen(..., 'a')的情况下判断file_exists()是否创建了新文件?

注意:这主要是风格和兴趣的问题,而不是真正的性能问题。但如果我弄错了并且fopen()已经检索到文件统计信息,请告诉我!

更新

好的,这确实是一个相当学术性的问题。这里有一些在Windows系统上运行的性能测试(Apache,Win8.1 - 没有UNIX文件权限)和一台linux机器(Nginx,Ubuntu 14.04,虚拟机)。

每次测试运行1000次重复,在第一次重复之前删除文件。

                                   Win    Linux
simply append one byte            1.8ms   9.4ms
append + clearstatcache()         1.8ms   9.3ms
test fileexists() + append        2.2ms  10.5ms
fileexists() + append + clear     2.2ms  11.0ms
append + chmod()                  2.7ms  12.3ms
append + fileexists() -> chmod()  3.3ms  10.6ms

注意:最后一个是在测试循环中使用和IF的唯一一个。

3 个答案:

答案 0 :(得分:2)

php fopen只是对libc fopen的调用,它会自动为模式w,w +,a和a +创建一个文件。据我所知,没有办法从返回的文件指针中获取带有权限位的stat

似乎PHP为每个打开的文件存储stat数组,您可以使用打开的文件句柄fstat($fp)使用$fp访问它。但mode字段包含inode permission bits。我无法立即看到" inode权限位" " UNIX文件模式" 的关系。 stat系统调用不使用此术语。

你可以使用" r +"模式打开您的文件,如果失败则创建它。如果不是你需要SEEK然后结束以实现类似的东西。

但最后在打开文件之前检查是否存在是最好的。

答案 1 :(得分:0)

不,fopen只返回资源,它不会返回或设置一个标志,指示文件是否已经存在 - http://php.net/manual/en/function.fopen.php

答案 2 :(得分:0)

编辑:请参阅编辑过的问题中的效果测试。

为什么不每次都致电chmod()? 你的file_exist()可能(可能是一点性能测试......)比chmod()更贵。

// Do the append
$f = fopen($filename, 'ab');
fwrite($f);
fclose($f);
// Update persmissions
@chmod($this->filename, 0666);