为何SplFileInfo返回错误文件大小?如何获取真实数据?
问题原因及解决方法
这个问题我之前在Windows环境下用PHP 7.x的时候也踩过坑,核心原因是SplFileInfo的属性缓存机制:
当你第一次调用getSize()或者其他获取文件属性的方法时,SplFileInfo会把文件的元数据(大小、修改时间这些)缓存到内存里。之后哪怕你修改了文件内容,默认情况下它不会主动去磁盘重新读取最新的文件状态,而是直接返回之前缓存的旧值——在Windows环境下这个表现会更突出,因为文件系统的变更通知机制和类Unix系统有差异,PHP没法自动感知文件的外部修改。
怎么拿到真实的文件大小?
有两种简单的解决办法:
1. 调用refresh()方法强制刷新缓存
这是最优解,不需要重新创建对象,直接让SplFileInfo重新读取磁盘上的文件属性:
<?php $fn = 'myfile.txt'; file_put_contents($fn, "abcd\n"); $fi = new \SplFileInfo($fn); echo '初始大小:' . $fi->getSize() . PHP_EOL; // 输出5(abcd加换行) // 修改文件内容 file_put_contents($fn, "abcdefghij\n"); // 强制刷新缓存,重新读取文件属性 $fi->refresh(); echo '修改后大小:' . $fi->getSize() . PHP_EOL; // 输出11(新内容加换行)
2. 重新实例化SplFileInfo对象
如果场景简单,也可以每次需要最新属性时,重新创建一个SplFileInfo实例,新对象会读取最新的文件状态:
<?php $fn = 'myfile.txt'; file_put_contents($fn, "abcd\n"); $fi = new \SplFileInfo($fn); echo '初始大小:' . $fi->getSize() . PHP_EOL; // 修改文件后,重新创建对象 file_put_contents($fn, "abcdefghij\n"); $fi = new \SplFileInfo($fn); echo '修改后大小:' . $fi->getSize() . PHP_EOL;
不过更推荐第一种方法,因为重复实例化对象会带来不必要的性能开销,尤其是频繁操作文件的场景。
内容的提问来源于stack exchange,提问作者lud
相关产品推荐
相关产品推荐

