2016-12-16 67 views
0

所寫的,我有file_put_contents附加在文件上的數據被其它進程

$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

如果你有多個進程(PHP應用程序),它們使用相同的'file_get_contents'寫入文件,你可以傳遞參數:'LOCK_EX',這是獲得在進行寫作時對文件進行獨佔鎖定。換句話說,在fopen()調用和fwrite()調用之間發生flock()調用。這與使用模式「x」的fopen()調用不同。 –

+0

你已經在做它。如果它不能寫入文件(另一個進程正在使用它),則失敗。 Coz,該函數返回寫入文件的字節數,或返回失敗時的FALSE。 –

回答

0

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毫秒後的第一個,但做第二個腳本之前寫。所以第二個腳本實際上訪問了一個鎖定文件。

  • 第二腳本termiated第一個

檢查結果之後寫入229毫秒後這兩個腳本終止執行:

$ stat -f%z /Volumes/myHD/somefile.txt 
100000010 
$ 

+ 10個字節被寫入10MB

$ tail -c 20 /Volumes/myHD/somefile.txt 
MORE-DATA 
$ 

第二個sc RIPT實際上是在文件的末尾附加字符串

0

的排他鎖很明顯,只有在你寫一個文件的時候才能使用它,如果你多次寫入同一個文件,你應該用fopen和fwrite自己處理它,當你寫完了。下面

基準:

file_put_contents()1,000,000寫入 - 平均3個基準:

真實0m3.932s 用戶0m2.487s SYS 0m1.437s

fopen()函數的fwrite( )1,000,000寫道,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); 

http://php.net/manual/en/function.file-put-contents.php