简体   繁体   English

如何重写同一个文件

[英]How to rewrite same file

Currently I'm doing it like this: 目前我这样做:

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

But I have a loop that does some expensive stuff (with files), and I'd like to avoid opening and closing the file handle every time I want to overwrite "test" 但我有一个循环,做一些昂贵的东西(有文件),我想避免每次我想覆盖“测试”时打开和关闭文件句柄

It should be something like this: 它应该是这样的:

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

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

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

  sleep(5); // just a example

}

fclose($f);

Is this possible? 这可能吗?

This script runs in the background in CLI mode and I'm reading the test file from the web with ajax like every 2 seconds. 这个脚本在CLI模式下在后台运行,我每隔2秒就用ajax从web上读取测试文件。 Basically I'm trying to display a progress bar lol 基本上我正在尝试显示进度条大声笑

You can update the content of a file by rewinding the file pointer, see fseek() . 您可以通过倒带文件指针来更新文件的内容,请参阅fseek() Be careful, once you set file lenght to N by writing N bytes to it, next time, if you rewind and write X < N bytes, the file will remain N bytes long, containing X bytes of new data and NX bytes of old stuff. 小心,一旦你通过向其写入N个字节将文件长度设置为N,下次,如果你倒回并写入X <N字节,文件将保持N字节长,包含X字节的新数据和NX字节的旧东西。

Anyway, don't worry about opening and closing files several times, they will be cached. 无论如何,不​​要担心多次打开和关闭文件,它们将被缓存。 Or you can open it on a ramdisk partition. 或者您可以在ramdisk分区上打开它。

You can keep the file and just rewrite over the contents, while then truncating the file if the size changed. 您可以保留文件并只重写内容,然后在大小更改时截断文件。 This will be faster than overwriting or deleting and rewriting. 这将比覆盖,删除和重写更快。

$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);

To go along with your example, you could implement your foverwrite() function using frewind() like this: 为了配合您的示例,您可以使用frewind()实现您的foverwrite()函数,如下所示:

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

This function will return fwrite() 's return value, so it can readily replace fwrite() where needed. 此函数将返回fwrite()的返回值,因此可以在需要时轻松替换fwrite() Also, in case of opening the file in append mode (a or a+) it will just append contens, as frewind() will make no difference. 此外,如果以附加模式(a或a +)打开文件,它将只附加竞争,因为frewind()将没有任何区别。

However, concerning the purpose of your script, which clearly is interprocess communication , you should take a look at more efficient techniques, like shared memory . 但是,关于脚本的目的,这显然是进程间通信 ,您应该看看更有效的技术,如共享内存

You can do it in following ways 您可以通过以下方式完成此操作

$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

If you're just aiming to keep a file updated so that it can be accessed by AJAX requests, then do you really need to update it 50000 times? 如果您的目标是保持文件更新以便AJAX请求可以访问它,那么您真的需要更新它50000次吗? A simple way of cutting your overhead would be to update the file less often. 减少开销的一种简单方法是更少地更新文件。 Like this, for example: 像这样,例如:

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");

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM