2

我有以下示例代码

<?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 显然成功了,但 file_get_contents 按预期失败。

fwrite 返回要写入的字节数是预期的行为吗?如果是这样,我如何测试写入是否真的成功?

这是 php 5.3.3

4

5 回答 5

5

它返回的原因false是文件指针在文件末尾之后fwrite......这就是fgets它到达文件末尾时应该做的事情(它返回false,因为没有更多数据要获取)......

你需要做的是fseek在你打电话之前添加一个电话fgets

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

编辑:现在我理解了你的问题(并看过它):

好的,这就是正在发生的事情。要理解,您必须首先了解 Linux 文件系统是如何工作的。文件名对操作系统没有意义。它所做的只是指向INODE文件。inode 存储数据等。它还存储指向该文件的硬链接数量的参考号。该文件仅在引用数降至 0 时被删除。我怀疑打开指向文件的指针(使用fopen或其他系统调用)会增加引用计数。

所以基本上,这意味着当你rm在文件上运行时,它删除了硬链接。但是由于文件仍然打开,您仍然可以通过它访问 inode fwrite(因此写入成功的原因)。/tmp/test.txt由于指向该文件名的硬链接不再存在,因此您无法访问。所以这个文件变成了一个只能被inode访问的幻像文件。但是,一旦您关闭该文件的文件句柄(fclose或通过结束脚本),引用计数就会下降到 0 并且 inode 被释放......

所以该文件确实存在,只是在您调用后无法从文件名访问rm...

这就是我通过了解我对文件系统的了解所收集的内容。我并不是说它是 100% 准确的,但它应该是一个不错的假设......

于 2010-11-18T14:21:23.200 回答
2

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

这是由于硬链接的工作方式;文件系统中的所有条目都是硬链接、软链接或设备。

于 2010-11-18T14:43:24.433 回答
0

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

 if (fwrite($handle, $somecontent) === FALSE) {
        echo "Cannot write to file ($filename)";
        exit;
 }
于 2010-11-18T14:17:44.277 回答
0

我相信你首先必须保存文件

fclose($f);
于 2010-11-18T14:22:52.520 回答
0

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

  • 检查文件是否存在
  • 文件是否可写
  • 数据是否写入文件
  • 数据是否可读
于 2010-11-18T14:25:23.900 回答