【问题标题】:Shared access: How to fix "fread(): Length parameter must be greater than 0"?共享访问:如何修复“fread():长度参数必须大于 0”?
【发布时间】:2020-02-06 19:36:06
【问题描述】:

当我在多个脚本上运行此功能时,一个脚本会生成警告: fread():长度参数必须大于0

function test($n){
  echo "<h4>$n at ".time()."</h4>";
  for ($i = 0; $i<50; $i++ ){    
  $fp = fopen("$n.txt", "r");
  $s = fread($fp, filesize("$n.txt") );
  fclose($fp);
  $fp = fopen("$n.txt", "w");
  $s = $_SERVER['HTTP_USER_AGENT'].' '.time();
  if (flock($fp, LOCK_EX)) {  // acquire an exclusive lock
      fwrite($fp, $s);
      // fflush($fp);// flush output before releasing the lock
      flock($fp, LOCK_UN);    // release the lock
    } else {
      echo "Couldn't get the lock!";
    }

  }
}

我尝试为多个用户写入文件读取,但只有一个用户可以写入文件。我知道当我将 fwrite 与flock - LOC_EX 一起使用时,下一个脚本必须等到写入完成。但是在这里似乎文件大小不会等到写操作完成。我的观点是,当文件大小为 0 时,它会尝试访问文件,因此会产生问题:当文件由原始脚本写入时,将从文件中读取 0 个字节。

是否可以为 fread 功能修复此问题?

这个脚本的目的是测试 fread 的一些限制,并检查我稍后读取的数据,如果数据真的是在我没有使用 fflush 时写入的。

【问题讨论】:

    标签: php fread filesize flock


    【解决方案1】:
        function test($n){
    echo "<h4>$n at ".time()."</h4>";
    for ($i = 0; $i<50; $i++ ){
      $start = microtime(true);
    
      $fp = fopen("$n.txt", "r");
      if(filesize($n.txt) > 0)
      {
        $s = fread($fp, filesize($n.txt) );
        fclose($fp);
        $fp = fopen("$n.txt", "w");
        $s = $_SERVER['HTTP_USER_AGENT'].' '.time();
         if (flock($fp, LOCK_EX)) {  // acquire an exclusive lock
         fwrite($fp, $s);
         // fflush($fp);// flush output before releasing the lock
         flock($fp, LOCK_UN);    // release the lock
         } else {
         echo "Couldn't get the lock!";
         }
      }
      else
      {
        echo "Filesize must be greater than 0";
      }
    
    
    
      }
     }
    
     please change $s variables name its use same things two time
    

    【讨论】:

    • 谢谢。我只是想看看文件是否被读取,它是。然后我将内容更改为 HTTP_USER_AGENT 只是为了测试
    • 等等,这真的是解决方案吗?我需要脚本等到原始脚本群发布。如果 fread 被跳过所以文件根本不被读取,这不是我想要实现的。
    【解决方案2】:
      $fp = fopen("$n.txt", "r");
      $s = fread($fp, filesize("$n.txt") );
      fclose($fp);
    

    错误出现在上述三行的中间一行。

    首先,这三行可以改写成一行:

    $s = file_get_contents("$n.txt");
    

    但是,这些不是必需的,因为这三行在您的代码中完全是多余的。他们没有做任何有用的事情。

    他们所做的是打开一个文件,将其内容存储到$s,然后关闭它。

    但是您随后会立即将 $s 设置为不同的值,从而丢弃先前的值,并且首先从文件中读取它毫无意义。

    如果您需要保留文件的原始内容,请使用file_get_contents() 并确保不要覆盖变量的内容。

    如果您不需要文件的原始内容,则只需从代码中删除这三行即可。

    顺便说一句,这个错误突出了您应该采取的几个良好的编码实践:首先,永远不要将变量重复用于两个不同的事物,其次始终为变量(和函数)起好名字。 $s 不是个好名字; $previousFileContents 会是一个更好的名字;它会使错误更加明显。

    【讨论】:

    • 我知道 file_get_contents 可以完成这项工作,但我正在测试 fread。从我的代码看来,似乎不可能使用 fread 来共享文件操作。我想测试是否可以使用 fread 安全地读取一些字节(在共享操作上)。似乎 fread 和 file_get_contents 的工作方式完全不同。我不能在 file_get_contents 之后执行 fflush,因为 file_get_contents 不接受文件句柄。
    猜你喜欢
    • 2021-06-12
    • 2020-04-01
    • 2016-01-28
    • 1970-01-01
    • 1970-01-01
    • 2018-03-30
    • 1970-01-01
    • 1970-01-01
    • 2016-08-25
    相关资源
    最近更新 更多