Как переписать тот же файл

В настоящее время я делаю так:

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

Но у меня есть цикл, который делает некоторые дорогие вещи (с файлами), и я бы хотел избежать открытия и закрытия дескриптора файла каждый раз, когда я хочу перезаписать "test"

Это должно быть примерно так:

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

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

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

  sleep(5); // just a example

}

fclose($f);

Возможно ли это?

Этот script работает в фоновом режиме в режиме CLI, и я читаю тестовый файл из Интернета с ajax, как каждые 2 секунды. В основном я пытаюсь отобразить индикатор выполнения lol

Ответ 1

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

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

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

Однако, что касается вашего script, который явно является межпроцессным обменом, вы должны взглянуть на более эффективные методы, например общая память.

Ответ 2

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

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

Ответ 3

Вы можете сохранить файл и просто переписать содержимое, а затем усечь файл, если размер изменится. Это будет быстрее, чем перезапись или удаление и переписывание.

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

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

  sleep(5);
}

fclose($f);

Ответ 4

Вы можете сделать это следующими способами.

$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

Ответ 5

Если вы просто хотите сохранить файл обновленным, чтобы его можно было получить по запросам 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");