2008-10-24 67 views
17

覆蓋文件中特定行的最佳方法是什麼?我基本上想搜索一個文件中的字符串'@parsethis',並用其他東西覆蓋該行的其餘部分。用PHP覆蓋文件中的行

回答

18

如果文件不是太大,最好的辦法可能是將文件讀入一個包含file()的行數組中,搜索字符串的行數並編輯該行,然後implode()數組返回一起和fwrite()它回到文件。

+1

這是我一直這樣做的。我會很好奇,看看是否有辦法在原地修改文件。 – 2008-10-24 23:42:00

-1

我很可能會做傑里米建議的事情,但只是另一種方法來做到這一點是另一種解決方案。這尚未經過測試或使用,適用於* nix系統。

$cmd = "grep '@parsethis' " . $filename; 
$output = system($cmd, $result); 
$lines = explode("\n", $result); 
// Read the entire file as a string 
// Do a str_repalce for each item in $lines with "" 
5

您的主要問題是,新行可能與舊行的長度不一樣。如果您需要更改該行的長度,那麼在更改後的行之後至少不能重寫所有文件。最簡單的方法是創建一個新的,修改後的文件,然後將其移動到原始文件上。這樣一來,讀者就可以隨時獲得完整的文件。使用鎖定來確保只有一個腳本一次修改文件,並且由於您要替換該文件,請對另一個文件執行鎖定。退房flock()

如果您確信,新的生產線將是相同長度的舊線,你可以打開讀取/寫入模式(使用r+作爲第二個參數fopen())文件,並調用ftell()保存位置在你撥打fgets()來讀取一行之前,每一行都會開始。一旦找到想要覆蓋的行,可以使用fseek()返回行的開頭,並使用fwrite()新數據。一種強制線條始終長度相同的方法是將空間填充到最大可能長度。

20

如果文件真的很大(日誌文件或類似的東西),並且你願意犧牲內存消耗的速度,你可以打開兩個文件,並且基本上用Jeremy Ruten來代替系統內存。

$source='in.txt'; 
$target='out.txt'; 

// copy operation 
$sh=fopen($source, 'r'); 
$th=fopen($target, 'w'); 
while (!feof($sh)) { 
    $line=fgets($sh); 
    if (strpos($line, '@parsethis')!==false) { 
     $line='new line to be inserted' . PHP_EOL; 
    } 
    fwrite($th, $line); 
} 

fclose($sh); 
fclose($th); 

// delete old source file 
unlink($source); 
// rename target file to source file 
rename($target, $source); 
0

,或者如果你的文件不是太大:

$sample = file_get_contents('sample'); 
$parsed =preg_replace('#@parsethis.*#', 'REPLACE TO END OF LINE', $sample); 

你必須選擇分隔符「#」是不存在的文件中雖然。