我发现了一个非常奇怪的File
行为[3] pry():1> File.zero?(file.path)
=> true
[4] pry():1> file.size
=> 3894
[5] pry():1> File.zero?(file.path)
=> false
来自[3]
和[5]
的真实文件大小可以通过在bash中检查来确认。
这种行为有解释吗?之前要提到的一点是,file.class
可能是File
或Tempfile
,并且在两种情况下都会发生。
答案 0 :(得分:3)
您看到这种看似奇怪的行为的原因是因为每个File
对象都有File::Stat object来封装有关文件的公共状态信息,该信息仅在采取触发更新的某些操作时更新。在这种情况下,触发器是您在文件上调用size
。您可以检查stat
对象以查看时间戳。
这是一个完全可重现的示例,其中引发了stat
调用。
irb(main):021:0* f = File.new "out", "w"
=> #<File:out>
irb(main):022:0> f.write "hi"
=> 2
irb(main):023:0> File.zero? f.path
=> true
irb(main):024:0> f.stat
=> #<File::Stat dev=0x801, ino=1062714, mode=0100664, nlink=1, uid=1000, gid=1000, rdev=0x0, size=0, blksize=4096, blocks=0, atime=2015-11-05 15:50:25 -0800, mtime=2015-11-05 15:52:08 -0800, ctime=2015-11-05 15:52:08 -0800>
irb(main):025:0> f.size # triggers an update
=> 2
irb(main):026:0> File.zero? f.path
=> false
irb(main):027:0> f.stat
=> #<File::Stat dev=0x801, ino=1062714, mode=0100664, nlink=1, uid=1000, gid=1000, rdev=0x0, size=2, blksize=4096, blocks=8, atime=2015-11-05 15:52:47 -0800, mtime=2015-11-05 15:52:45 -0800, ctime=2015-11-05 15:52:45 -0800>
虽然,我认为在write
对象上调用File
会触发更新。
编辑:我弄清楚为什么write
不会触发更新。 write
是File
的父类(IO
)的方法。但size
和stat
都是File
的方法。因此,必须在write
中实施File
方法才能访问(或了解)stat
。我怀疑对File
中实施的方法的任何调用都会更新stat
。