【问题标题】:fwrite writes NULfwrite 写入 NUL
【发布时间】:2013-08-15 15:12:57
【问题描述】:

我正在尝试使用 PHP 写入文件,这是我正在使用的代码(取自 this answer 到我之前的问题):

$fp = fopen("counter.txt", "r+");

while(!flock($fp, LOCK_EX)) {  // acquire an exclusive lock
    // waiting to lock the file
}

$counter = intval(fread($fp, filesize("counter.txt")));
$counter++;

ftruncate($fp, 0);      // truncate file
fwrite($fp, $counter);  // set your data
fflush($fp);            // flush output before releasing the lock
flock($fp, LOCK_UN);    // release the lock

fclose($fp);

读取部分工作正常,如果文件被读取,则其内容被读取良好,即如果文件包含2289,则读取2289

问题在于,当它递增并将值重写到该文件时,[NUL][NUL][NUL][NUL][NUL][NUL][NUL][NUL]1 会被写入。

我错过了什么?为什么会写入空字符?

【问题讨论】:

  • 这是次要的,但这里的锁定代码很奇怪。如果没有LOCK_NB 标志,flock 将阻塞直到它可以获取锁,因此循环等待它返回true 是没有意义的。它在没有LOCK_NB 的情况下返回false 的唯一原因是,如果您未能打开文件并将null 作为第一个参数传递,那么等待肯定无济于事......而且循环意味着您将在这种情况下无限循环地发出警告。
  • @MarkAmery 我从来都不是 PHP 专家,尤其是在 2013 年,我才刚刚开始职业生涯,所以这肯定是初学者的错误 :) 感谢您指出这一点!跨度>

标签: php file fwrite nul


【解决方案1】:

您缺少的是 rewind()。没有它,在你截断到 0 字节后,指针仍然不在开头(reference)。因此,当您编写新值时,它会在您的文件中使用NULL 填充它。

此脚本将读取一个文件(如果不存在则创建)以获取当前计数、递增,然后在每次页面加载时将其写回同一个文件。

$filename = date('Y-m-d').".txt";

$fp = fopen($filename, "c+"); 
if (flock($fp, LOCK_EX)) {
    $number = intval(fread($fp, filesize($filename)));
    $number++;

    ftruncate($fp, 0);    // Clear the file
    rewind($fp);          // Move pointer to the beginning
    fwrite($fp, $number); // Write incremented number
    fflush($fp);          // Write any buffered output
    flock($fp, LOCK_UN);  // Unlock the file
}
fclose($fp);

【讨论】:

  • 这让我发疯了,我大吃一惊,以为是字符编码、BOM 等。原来是这个!非常感谢
  • 这应该是公认的答案。它解释了问题中NUL 条目的原因。
【解决方案2】:

编辑#2:

用羊群试试这个(测试)

如果文件没有被锁定,它会抛出一个异常(见添加的行)if(...

我从 this accepted answer 借用了 Exception sn-p。

<?php

$filename = "numbers.txt";
$filename = fopen($filename, 'a') or die("can't open file");

if (!flock($filename, LOCK_EX)) {
    throw new Exception(sprintf('Unable to obtain lock on file: %s', $filename));
}

file_put_contents('numbers.txt', ((int)file_get_contents('numbers.txt'))+1);

// To show the contents of the file, you 
// include("numbers.txt");

    fflush($filename);            // flush output before releasing the lock
    flock($filename, LOCK_UN);    // release the lock


fclose($filename);
echo file_get_contents('numbers.txt');

?>

【讨论】:

    【解决方案3】:

    你可以使用这个代码,一个简化的版本,但不确定它是否是最好的:

    <?php
    $fr = fopen("count.txt", "r");
    $text = fread($fr, filesize("count.txt"));
    $fw = fopen("count.txt", "w");
    $text++;
    fwrite($fw, $text);
    ?>
    

    【讨论】:

      猜你喜欢
      • 2021-05-14
      • 2021-02-16
      • 2011-05-20
      • 2014-07-09
      • 2023-03-03
      • 1970-01-01
      • 2020-08-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多