代码之家  ›  专栏  ›  技术社区  ›  Rwky

即使文件不存在,PHP Frad也总是返回要写入的字节数,这是预期的行为吗?

  •  2
  • Rwky  · 技术社区  · 14 年前

    我有下面的示例代码

    <?php
    `echo test > /tmp/test.txt`;
    $f=fopen("/tmp/test.txt","w+");
    `rm /tmp/test.txt`;
    var_dump(fwrite($f,"test"));
    fclose($f);
    file_get_contents("/tmp/test.txt");
    

    它创建一个文件,打开指向该文件的指针,删除该文件,然后尝试写入该文件。现在我希望fwrite返回false或0,因为不会写入任何数据,但是它会产生以下输出

    int(4)
    
    Warning: file_get_contents(/tmp/test.txt): failed to open stream: No such file or directory in /Stuff/tmp/test3 on line 7
    

    因此,fwrite显然成功了,但文件获取内容却如预期的那样失败了。

    fwrite是否期望返回要写入的字节数?如果是这样的话,我如何测试这篇文章是否真的成功了呢?

    这是PHP5.3.3

    5 回复  |  直到 12 年前
        1
  •  5
  •   ircmaxell    14 年前

    它回来的原因 false 文件指针在 fwrite ... 那就是 fgets 当它到达文件末尾时(它返回 因为没有更多的数据可以获取。。。

    你需要做的是添加 fseek 先打电话再打 fgets公司 :

    var_dump(fwrite($f,"test"));
    fseek($f, 0);
    var_dump(fgets($f));
    

    编辑: 现在我明白了你的问题(并且已经看过了):

    好吧,现在发生了什么。要理解这一点,首先必须了解Linux文件系统是如何工作的。文件名对操作系统没有意义。它所做的就是指向 INODE 为了文件。inode存储数据等。它还存储 hard-links 到那个档案。只有当引用号降至0时,才会删除该文件。我怀疑打开指向文件的指针(使用 fopen ,或其他系统调用)增加引用计数。

    所以基本上,这意味着当你跑步的时候 rm 在文件中,它删除了硬链接。但是由于文件仍然打开,您仍然可以通过 写入文件 (因此写得成功)。你无法访问 /tmp/test.txt 因为那个文件名的硬链接已经不存在了。因此,该文件变成了一个只有inode才能访问的幻影文件。但是一旦你关闭了那个文件的文件句柄( fclose ,或者通过结束脚本)引用计数降为0,索引节点被释放。。。

    所以文件确实存在,在调用之后无法从文件名访问 ...

    这正是我通过了解有关文件系统的知识而收集到的信息。我不是说它是100%准确的,但它应该是一个像样的假设。。。

        2
  •  2
  •   Powerlord    14 年前

    如果这是在Linux(以及可能的其他类似于unix的操作系统)系统上,文件系统中对文件的引用将被删除 rm ,但是文件本身仍然存在,直到从其上读取/写入的所有程序都被关闭。

    这是因为 hard links 工作;文件系统中的所有条目都是硬链接, soft links ,或设备。

        3
  •  0
  •   pestaa    14 年前

    我相信你必须先保存文件

    fclose($f);
    
        4
  •  0
  •   Jose Vega    14 年前

    下面的代码应该允许您检查它是否成功写入。

     if (fwrite($handle, $somecontent) === FALSE) {
            echo "Cannot write to file ($filename)";
            exit;
     }
    
        5
  •  0
  •   takeshin    14 年前

    您的代码需要一些条件,例如错误处理。

    • 检查文件是否存在
    • 文件是否可写
    • 数据是否写入文件
    • 数据是否可读