【问题标题】:weird PHP filesize behavior奇怪的 PHP 文件大小行为
【发布时间】:2014-07-19 01:49:04
【问题描述】:

在下面的代码中我...

  1. 打开一个文本文件,写入四个字符,然后再次关闭,

  2. 重新打开,读取内容,使用filesize报告文件大小。 (应该是 4),

  3. 处理这些内容并添加另外四个字符。然后我将该新字符串写入文本文件并再次关闭它,

  4. 再次使用 filesize 来报告文件的大小。

令我惊讶的是,即使文件的实际大小是 8,它给出的答案仍然是 4!检查文件内容证明写入有效,内容长度为8。

发生了什么事??

顺便说一句,我必须使用 fread 和 fwrite 而不是 file_get_contents 和 file_put_contents。至少我认为我会。这个小程序是使用“flock”的垫脚石,所以我可以读取文件的内容并重写它,同时确保没有其他进程在中间使用该文件。而且 AFAIK 群不适用于 file_get_contents 和 file_put_contents。

请帮忙!

<?php
$filename = "blahdeeblah.txt";

// Write 4 characters
$fp = fopen($filename, "w");
fwrite($fp, "1234");
fclose($fp);

// read those characters, manipulate them, and write them back (also increasing filesize).
$fp = fopen($filename, "r+");
$size = filesize($filename);
echo "size before is: " . $size . "<br>";
$t = fread($fp, $size);
$t = $t[3] . $t[2] . $t[1] . $t[0] . "5678";
rewind($fp);
fwrite($fp, $t);
fclose($fp);

// "filesize" returns the same number as before even though the file is larger now.
$size = filesize($filename);
echo "size after is: " . $size . "   ";

?>

【问题讨论】:

    标签: php fopen fwrite filesize fread


    【解决方案1】:

    来自http://php.net/manual/en/function.filesize.php

    注意:此函数的结果会被缓存。详情请见clearstatcache()

    【讨论】:

    • 万岁!我知道这必须是一些挑剔的细节。对于 Pete 而言,如果程序员在一个脚本中多次使用文件大小 - 而不是只使用一次并将值分配给变量 - 那么显然这是因为文件大小可能会在两者之间发生变化。该死的PHP。无论如何,感谢 CJ 丹尼斯!你摇滚!
    • 我认为缓存文件大小是有意义的。这可能是一个昂贵的调用(特别是如果通过网络完成),并且大多数文件通常不会经常改变大小,如果有的话。没有什么可以阻止糟糕的程序员在循环中一遍又一遍地检查同一个文件!
    • 我听到了,但对我来说,这种“特性”使得如果一个确实犯了这样一个代价高昂的错误的程序员可能永远不会知道它为什么不好。它默许草率的编码。但是,嘿,我想人们(包括我)学会使用 C 以外的语言是有原因的。再次感谢 CJ Dennis。
    • 对于缓存filesize(),我会投 80% 的赞成票和 20% 的反对票。我可以看到优点和缺点,但我相信优点大于缺点。如果您检查两个不相关的类中的文件大小怎么办?仅仅为了缓存它们之间的大小而传递一个变量会很麻烦(甚至不要提及global!)让PHP为您缓存大小更容易。无论语言有多严格/限制,糟糕的程序员总会找到编写糟糕代码的方法!糟糕的程序员不关心或需要更多的教育,或者不应该成为程序员。我们无法阻止它!
    • 哈哈!你提出了一个有说服力的论点 CJ Dennis :-)
    【解决方案2】:

    当您通过 fopen() 函数打开文件时,您可以使用 fstat() 函数随时获得适当的大小

    $fstat=fstat($fp);
    echo 'Size: '.$fstat['size'];
    

    例子:

    $filename='blahdeeblah.txt';
    
    $fp=fopen($filename, 'a');
    
    $size=@filesize($filename);
    echo 'Proper size (obtained by filesize): '.$size.'<br>';
    
    $fstat=fstat($fp);
    echo 'Proper size (obtained by fstat): '.$fstat['size'].'<br><br>';
    
    fwrite($fp, '1234');
    echo 'Writing 4 bytes...<br><br>';
    
    $fstat=fstat($fp);
    echo 'Proper size (obtained by fstat): '.$fstat['size'].'<br>';
    
    fclose($fp);
    
    $size=@filesize($filename);
    echo 'Wrong size (obtained by filesize): '.$size;
    

    【讨论】:

      【解决方案3】:

      请注意,缓存值仅在当前脚本中使用。当您再次运行脚本时,filesize() 会读取新的(正确的)文件大小。 示例:

      $filename='blahdeeblah.txt';
      
      $fp=fopen($filename, 'a');
      
      $size=@filesize($filename);
      echo 'Proper size: '.$size.'<br>';
      
      fwrite($fp, '1234');
      fclose($fp);
      
      $size=@filesize($filename);
      echo 'Wrong size: '.$size;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-12-31
        • 2013-08-08
        • 2021-07-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-10-25
        • 2016-02-22
        相关资源
        最近更新 更多