【问题标题】:How to rewrite same file如何重写同一个文件
【发布时间】:2013-10-19 17:48:37
【问题描述】:

目前我正在这样做:

$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 读取测试文件。基本上我试图显示一个进度条lol

【问题讨论】:

  • 你真正想要达到什么目的? AKA,您的文件在之前和之后的输出是什么?
  • 为什么不直接在循环中准备一个字符串,然后将其写入文件???
  • 但这就是我正在做的,$i 是字符串 :) zonzon:它只是一行:i = number(循环中的数字变化)
  • 我还是没有得到你想要的,你想覆盖整个文件吗?如果你想显示一个进度条,你应该只写一行当前进度的百分比。
  • 是的,这正是我想要的,但如果可能的话,每次我这样做时都不要打开和关闭文件

标签: php file-io


【解决方案1】:

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

不管怎样,不用担心多次打开和关闭文件,它们会被缓存。或者你可以在 ramdisk 分区上打开它。

【讨论】:

    【解决方案2】:

    您可以保留文件并仅重写内容,然后在大小更改时截断文件。这将比覆盖或删除和重写更快。

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

    【讨论】:

      【解决方案3】:

      为了配合您的示例,您可以像这样使用 frewind() 实现您的 foverwrite() 函数:

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

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

      但是,关于脚本的用途,显然是 interprocess communication,您应该看看更有效的技术,例如 shared memory

      【讨论】:

        【解决方案4】:

        如果您的目标只是保持文件更新以便 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");
        

        【讨论】:

          【解决方案5】:

          你可以通过以下方式做到这一点

          $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
          

          【讨论】:

          • 您的意思是$i &lt; 50000 作为条件吗? (目前你只有$ 变量)。
          猜你喜欢
          • 1970-01-01
          • 2017-03-17
          • 2012-07-07
          • 2019-10-13
          • 1970-01-01
          • 2012-05-04
          • 1970-01-01
          • 2013-03-23
          • 2013-07-06
          相关资源
          最近更新 更多