file_put_contents 在另一个进程正在写入的文件上追加数据
file_put_contents appending data on a file being written by another process
我有
$bytesCount = file_put_contents( "somefile.log", "some text\n", FILE_APPEND | LOCK_EX );
如果另一个进程正在 somefile.log
上写入**会怎样?
file_put_contents
是否因运行时错误而失败?
如果 $bytesCount === false
失败则执行
还是暂停脚本直到文件解锁,然后执行写入操作?
(**) 或更一般地,另一个进程对该文件具有独占锁
[ 我在 *nix
平台上 php 5.6 ]
很明显,这应该只在你写一次时使用,如果你多次写同一个文件,你应该用 fopen 和 fwrite 自己处理,写完后的 fclose .
基准如下:
file_put_contents() 1,000,000 次写入 - 3 个基准的平均值:
实际 0m3.932s
用户 0m2.487s
系统 0m1.437s
fopen() fwrite() 1,000,000 次写入,fclose() - 3 个基准的平均值:
实际 0m2.265s
用户 0m1.819s
系统 0m0.445s
对于使用 ftp 时的覆盖,这很有帮助:
/* create a stream context telling PHP to overwrite the file */
$options = array('ftp' => array('overwrite' => true));
$stream = stream_context_create($options);
当 file_put_contents
尝试写入锁定的文件时 等待文件解锁然后执行写入 和 returns 写入的字节数。
证明:
我写了一个简单的双脚本测试:
第一个脚本写入一个 100MB 的文件(在连接 USB2 的慢速驱动器上);
第二个脚本将一个短字符串附加到同一个文件。
两个脚本的核心就是这四行:
echo Milliseconds() . ": Start writing file on file\n";
$bytesCount = file_put_contents( "/Volumes/myHD/somefile.txt", $buffer, FILE_APPEND | LOCK_EX );
var_export( $bytesCount );
echo "\n" . Milliseconds() . ": Done writing on file\n";
其中 Milliseconds()
是 returns 当前 unix 时间戳(以毫秒为单位)的函数。
在第一个脚本中 $buffer
是一个 100MB 的字符串,在第二个脚本中 $buffer = "MORE-DATA\n";
运行 第一个脚本并快速启动第二个脚本导致此输出:
脚本 1:
$ php test1.php
1481892766645: Start writing file on file
100000000
1481892769680: Done writing on file
$
脚本 2:
$ php test2.php
1481892766831: Start writing file on locked file
10
1481892769909: Done writing file on locked file
$
注意:
第二个脚本在第一个脚本之后 186 毫秒尝试写入,但在第二个脚本完成写入之前。所以第二个脚本实际上访问了一个锁定的文件。
第二个脚本在第一个脚本后 229 毫秒终止写入
检查两个脚本终止执行后的结果:
$ stat -f%z /Volumes/myHD/somefile.txt
100000010
$
已写入 10MB + 10 个字节
$ tail -c 20 /Volumes/myHD/somefile.txt
0123456789MORE-DATA
$
第二个脚本实际上是在文件末尾追加了字符串
我有
$bytesCount = file_put_contents( "somefile.log", "some text\n", FILE_APPEND | LOCK_EX );
如果另一个进程正在 somefile.log
上写入**会怎样?
file_put_contents
是否因运行时错误而失败?
如果 $bytesCount === false
还是暂停脚本直到文件解锁,然后执行写入操作?
(**) 或更一般地,另一个进程对该文件具有独占锁
[ 我在 *nix
平台上 php 5.6 ]
很明显,这应该只在你写一次时使用,如果你多次写同一个文件,你应该用 fopen 和 fwrite 自己处理,写完后的 fclose .
基准如下:
file_put_contents() 1,000,000 次写入 - 3 个基准的平均值:
实际 0m3.932s 用户 0m2.487s 系统 0m1.437s
fopen() fwrite() 1,000,000 次写入,fclose() - 3 个基准的平均值:
实际 0m2.265s 用户 0m1.819s 系统 0m0.445s
对于使用 ftp 时的覆盖,这很有帮助:
/* create a stream context telling PHP to overwrite the file */
$options = array('ftp' => array('overwrite' => true));
$stream = stream_context_create($options);
当 file_put_contents
尝试写入锁定的文件时 等待文件解锁然后执行写入 和 returns 写入的字节数。
证明:
我写了一个简单的双脚本测试:
第一个脚本写入一个 100MB 的文件(在连接 USB2 的慢速驱动器上);
第二个脚本将一个短字符串附加到同一个文件。
两个脚本的核心就是这四行:
echo Milliseconds() . ": Start writing file on file\n";
$bytesCount = file_put_contents( "/Volumes/myHD/somefile.txt", $buffer, FILE_APPEND | LOCK_EX );
var_export( $bytesCount );
echo "\n" . Milliseconds() . ": Done writing on file\n";
其中 Milliseconds()
是 returns 当前 unix 时间戳(以毫秒为单位)的函数。
在第一个脚本中 $buffer
是一个 100MB 的字符串,在第二个脚本中 $buffer = "MORE-DATA\n";
运行 第一个脚本并快速启动第二个脚本导致此输出:
脚本 1:
$ php test1.php
1481892766645: Start writing file on file
100000000
1481892769680: Done writing on file
$
脚本 2:
$ php test2.php
1481892766831: Start writing file on locked file
10
1481892769909: Done writing file on locked file
$
注意:
第二个脚本在第一个脚本之后 186 毫秒尝试写入,但在第二个脚本完成写入之前。所以第二个脚本实际上访问了一个锁定的文件。
第二个脚本在第一个脚本后 229 毫秒终止写入
检查两个脚本终止执行后的结果:
$ stat -f%z /Volumes/myHD/somefile.txt
100000010
$
已写入 10MB + 10 个字节
$ tail -c 20 /Volumes/myHD/somefile.txt
0123456789MORE-DATA
$
第二个脚本实际上是在文件末尾追加了字符串