ruby IO.read()是否锁定?

时间:2009-08-31 23:59:12

标签: ruby-on-rails ruby

我有一个webservice方法,可以读取照片并返回其字节数据。我目前正在做以下事情:

@photo_bytes = IO.read("/path/to/file")
send_data(@photo_bytes, :filename => "filename", :type => "filetype", :disposition => "inline")

我在调用它时遇到了一些奇怪的行为......偶尔send_data会返回null。我想如果文件还没有关闭,我可能会得到读取争用。用IO.read打开文件后是否需要显式关闭文件?我怎么能用read_nonblock来做这件事并且值得吗?

更新:

所以我做了一些更多的日志记录,偶尔IO.read返回一个像1800字节的值,当它通常返回〜5800字节的图片。当它返回1800字节时,图片不会显示在客户端上。当两个用户正在调用Web服务时,这种情况会相当随机发生。

由于

汤姆

1 个答案:

答案 0 :(得分:4)

IO.read方法不会执行任何建议文件锁定,因此不应受其他并发读取器的影响。但是,如果应用程序中的其他位置的代码写入到同一路径,则需要确保以原子方式更新文件。以write(not append)模式打开文件会立即将文件截断为零字节,因此在编写新版本之前,您可以看到从上面的代码段生成的空响应。

假设您使用的是Linux或OS X之类的* NIX平台,您可以使用以下代码原子更新文件:

require 'tempfile'
require 'fileutils'

def safe_write(path, data)
  tmp = Tempfile.new
  tmp.write(data)
  tmp.close
  FileUtils.mv(tmp.path, path)
end

这会将数据写入临时文件,然后以原子方式将其移至"/path/to/file"位置,而无需读者看到零长度截断版本。