这是我的pry会话输出:
[1] pry(SomeTask)> epub
=> #<File:/somepath/tmp/x.epub>
[2] pry(SomeTask)> epub.size
=> 134
[3] pry(SomeTask)> File.size("/somepath/tmp/x.epub")
=> 44299
[4] pry(SomeTask)> epub.class
=> Tempfile
我看到File.size
产生的结果与Tempfile实例的size
方法不同。
这怎么可能?
答案 0 :(得分:3)
魔鬼在于细节。来自Tempfile#size
的文件(强调我的):
<强>尺寸()强>
返回临时文件的大小。 作为副作用,在确定大小之前刷新IO缓冲区。
发生的事情是你在刷新缓冲区之前使用File.size
来读取文件的大小 - 即。在所有字节都写入文件之前 - 然后你使用Tempfile#size
,它会在计算大小之前刷新缓冲区:
tmp = Tempfile.new('foo')
tmp.write('a' * 1000)
File.size(tmp)
# => 0
tmp.size
# => 1000
但是看看在 tmp.size
之前致电File.size(tmp)
时会发生什么:
tmp = Tempfile.new('bar')
tmp.write('a' * 1000)
tmp.size
# => 1000
File.size(tmp)
# => 1000
您可以通过手动刷新缓冲区来获取File.size
之外的行为:
tmp = Tempfile.new('baz')
tmp.write('a' * 1000)
tmp.flush
File.size(tmp)
# => 1000
答案 1 :(得分:0)
我在Ruby 2.2.2上使用Pry版本0.10.1并且不能复制这种情况:
[1] (pry) main: 0> foo = Tempfile.new('foo')
#<File:/var/folders/yb/whn8dwns6rl92jswry5cz87dsgk2n1/T/foo20150819-83612-1tpkqm4>
[2] (pry) main: 0> File.size(foo.path)
=> 0
[3] (pry) main: 0> foo.size
=> 0
初始化后,文件大小为0字节。
[4] (pry) main: 0> foo.write('a')
=> 1
[5] (pry) main: 0> File.size(foo.path)
=> 0
将一个字符写入foo
后,数据已被缓冲,而不是像我期望的那样刷新到磁盘。
[6] (pry) main: 0> foo.size
=> 1
[7] (pry) main: 0> File.size(foo.path)
=> 1
foo.size
刷新缓冲区然后返回文件的大小,该大小与File.size
所说的匹配。
在处理Tempfile创建的临时文件时,我们不关心或想知道它们的大小。它们是暂时的并且会消失(最终)并被视为缓冲区。如果您需要一个更永久的文件,那么创建并写入普通文件。