2013-10-08 24 views
12

目前我正在做這樣的:如何重寫同一個文件

$f = fopen('test', 'w'); 
fwrite($f, 'Hi'); 
fclose($f); 

但是我有一個循環,做一些昂貴的東西(有文件),我想避免打開和關閉文件句柄我要覆蓋「測試」

應該是這樣的,每次:

$f = fopen('test', 'w'); 

$i = 0; 
while($ < 50000){ 

    $i++; 
    foverwrite($f, 'i = ' . $i); 

    sleep(5); // just a example 

} 

fclose($f); 

這可能嗎?

這個腳本在CLI模式下運行在後臺,我正在從web上用ajax像每2秒讀一個測試文件。基本上我試圖顯示進度條lol

+0

你究竟在努力達到什麼目的? AKA,之前和之後的文件輸出是什麼? – zonzon

+1

爲什麼你不準備在該循環內準備一個字符串,然後將其寫入文件? – Yang

+0

但這就是我正在做的,$我是字符串:) zonzon:它只是一條線:我=數字(在循環中的數量變化) – thelolcat

回答

2

當您例如一起去,你可以使用frewind()這樣實現你foverwrite()功能:

function foverwrite($handle,$content) 
    { 
    frewind($handle); 
    return fwrite($handle,$content); 
    } 

該函數將返回fwrite()的返回值,所以它在需要時可隨時替換fwrite()。另外,如果在追加模式下打開文件(a或a +),它只會追加競標,因爲frewind()將不會有任何區別。

然而,關於你的腳本,這顯然是interprocess communication的目的,你應該看看更有效的技術,像shared memory

9

您可以通過倒回文件指針來更新文件的內容,請參閱fseek()。請注意,一旦將文件長度設置爲N,通過向其寫入N個字節,下次,如果您倒帶並寫入N個字節,則該文件將保持N個字節,包含X字節的新數據和舊字節的NX字節。

無論如何,不​​要擔心打開和關閉文件多次,它們會被緩存。或者你可以在虛擬硬盤分區上打開它。

1

您可以在以下幾個方面

$data = [];//initiate the $data variable as empty array 
$i = 0; 
while($i < 50000){ 

    $data[] = 'i = ' . $i; 
    $i++; 
} 
file_put_contents('file.txt', implode("\n", $data));// implode the array 
+0

你的意思是'$我<50000'作爲條件? (目前你只有'$'的變量)。 – Flexo

8

可以保留文件,只是在改寫的內容,而然後截斷該文件,如果大小改變這樣做。這將比覆蓋或刪除和重寫更快。

$f = fopen('test', 'w'); 
$i = 0; 
while($i < 50000){ 
    $i++; 

    rewind($f); 
    $data = 'i = ' . $i; 
    fwrite($f, $data); 
    ftruncate($f, strlen($data)); // <---------- Here's the ticket 

    sleep(5); 
} 

fclose($f); 
1

如果你只是旨在及時更新,以便它可以通過AJAX請求訪問的文件,那麼你真的需要更新它50000次?減少開銷的簡單方法是更新文件的次數減少。與此類似,例如:

for ($i=0; $i<50000; $i++) { 

    // update progress file every 1000 iterations: 
    if (!($i % 1000)) file_put_contents('./file.txt', "i = $i"); 

    // --- do stuff --- 

} 
file_put_contents($f, "i = 50000");