首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PHP fwrite总是返回要写入的字节数,即使文件不存在,这是预期的行为吗?

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

Stack Overflow用户
提问于 2010-11-18 22:13:20
回答 5查看 1.9K关注 0票数 2

我有以下示例代码

代码语言:javascript
复制
<?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,因为不会写入任何数据,但是它会产生以下输出

代码语言:javascript
复制
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实现的

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2010-11-18 22:21:23

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

您需要做的是在调用fgets之前添加一个fseek调用

代码语言:javascript
复制
var_dump(fwrite($f,"test"));
fseek($f, 0);
var_dump(fgets($f));

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

好的,这就是发生的事情。要理解这一点,您必须首先了解Linux文件系统的工作原理。该文件的名称对操作系统没有任何意义。它所要做的就是指向文件的INODE。inode存储数据等。它还存储对该文件的hard-links编号的引用编号。仅当引用编号为0时,才删除该文件。我怀疑打开指向文件的指针(使用fopen或其他系统调用)会增加引用计数。

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

所以这个文件确实存在,只是在你调用rm之后无法从文件名中访问它...

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

票数 5
EN

Stack Overflow用户

发布于 2010-11-18 22:43:24

如果这是在Linux (可能还有其他类unix的OSes)系统上,rm会删除文件系统中对该文件的引用,但该文件本身仍然存在,直到所有读/写它的程序都关闭为止。

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

票数 2
EN

Stack Overflow用户

发布于 2010-11-18 22:17:44

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

代码语言:javascript
复制
 if (fwrite($handle, $somecontent) === FALSE) {
        echo "Cannot write to file ($filename)";
        exit;
 }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4215653

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档