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 模式在后台运行,我每隔 2 秒就使用 ajax 从 Web 读取测试文件。基本上我正在尝试显示进度条哈哈

4

5 回答 5

9

您可以通过倒回文件指针来更新文件的内容,请参阅fseek()。小心,一旦你通过写入 N 个字节将文件长度设置为 N,下一次,如果你倒带并写入 X < N 字节,文件将保持 N 字节长,包含 X 字节的新数据和 NX 字节的旧数据.

无论如何,不​​要担心多次打开和关闭文件,它们会被缓存。或者您可以在 ramdisk 分区上打开它。

于 2013-10-08T14:00:26.357 回答
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);
于 2013-10-16T21:28:50.033 回答
2

为了配合您的示例,您可以使用如下方式实现您的foverwrite()功能:frewind()

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

此函数将返回fwrite()的返回值,因此可以fwrite()在需要的地方轻松替换。此外,如果以附加模式(a 或 a+)打开文件,它只会附加内容,frewind()没有区别。

但是,关于脚本的目的,显然是进程间通信,您应该看看更有效的技术,例如共享内存

于 2013-10-19T09:35:21.293 回答
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
于 2013-10-16T07:24:54.693 回答
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");
于 2013-10-18T22:17:44.587 回答