2013-10-08 5 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, и я читаю тестовый файл из Интернета с помощью ajax, как каждые 2 секунды. В основном я пытаюсь отобразить индикатор выполнения lol

+0

Что вы на самом деле пытаетесь достичь? AKA, какой будет выход вашего файла до и после? – zonzon

+1

Почему бы вам просто не подготовить строку внутри этого цикла, а затем записать ее в файл ??? – Yang

+0

Но это то, что я делаю, $ i - это строка :) zonzon: это будет просто строка: i = число (число изменений в цикле) – thelolcat

ответ

2

идти вместе с вашим примером, вы могли бы реализовать foverwrite() функцию, используя frewind() так:

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

Эта функция возвращает fwrite() «s возвращаемое значение, так что может легко заменить fwrite() там, где это необходимо. Кроме того, в случае открытия файла в режиме добавления (a или +) он просто добавит contens, так как frewind() не имеет значения.

Однако относительно цели вашего сценария, который явно является interprocess communication, вы должны смотреть на более эффективные методы, как shared memory.

9

Вы можете обновить содержимое файла, перематывая указатель файла, см. fseek(). Будьте осторожны, как только вы установите длину файла на N, записав в него N байтов, в следующий раз, если вы перемотаете и напишите X < N байтов, файл останется длиной N байтов, содержащий X байтов новых данных и байты NX старого материала ,

В любом случае, не беспокойтесь об открытии и закрытии файлов несколько раз, они будут кэшироваться. Или вы можете открыть его на разделе ramdisk.

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

Вы имели в виду '$ i <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"); 
Смежные вопросы