我有
$bytesCount = file_put_contents( "somefile.log", "some text\n", FILE_APPEND | LOCK_EX );
如果另一个流程在somefile.log
上写**,会发生什么?
file_put_contents
是否因运行时错误而失败?
如果失败了$bytesCount === false
或者它是否暂停脚本直到文件解锁然后执行写操作?
(**)或更一般地说,另一个进程对文件具有独占锁定
[我在*nix
平台上使用php 5.6 ]
答案 0 :(得分:1)
当file_put_contents
尝试在锁定文件上写入时等待文件解锁,然后执行写入并返回写入的字节数。
<强>证明:强>
我写了一个简单的双脚本测试:
第一个脚本写入一个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()
是一个以毫秒为单位返回当前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
$
第二个脚本实际上在文件末尾添加了字符串
答案 1 :(得分:0)
很明显,只有在你进行一次写操作时才能使用它,如果你多次写入同一个文件,你应该用fopen和fwrite自己处理它,当你写完文件时fclose
以下基准:
file_put_contents(),用于1,000,000次写入 - 平均3个基准:
真正的0m3.932s 用户0m2.487s sys 0m1.437s
fopen()用于1,000,000次写入的fwrite(),fclose() - 平均3个基准:
真正的0m2.265s 用户0m1.819s sys 0m0.445s
对于使用ftp时的覆盖,这很有帮助:
/* create a stream context telling PHP to overwrite the file */
$options = array('ftp' => array('overwrite' => true));
$stream = stream_context_create($options);