在Ruby on Rails中获取空临时目录的最佳方法是什么?

Mik*_*ike 31 ruby ruby-on-rails

使用Ruby on Rails获取其中没有任何内容的临时目录的最佳方法是什么?我需要API与跨平台兼容.stdlib tmpdir不起作用.

Jus*_*ner 51

Dir对象有一个方法mktmpdir,它创建一个临时目录:

require 'tmpdir' # Not needed if you are using rails.

Dir.mktmpdir do |dir|
  puts "My new temp dir: #{dir}"
end
Run Code Online (Sandbox Code Playgroud)

执行块后将删除临时目录.

  • 来自[ruby-doc.org](http://ruby-doc.org/stdlib-2.0.0/libdoc/tmpdir/rdoc/Dir.html#method-c-mktmpdir)_如果没有给出一个块,路径的目录是返回的.在这种情况下,:: mktmpdir不会删除目录._ (11认同)
  • @JamieCook示例:在RSpec`after`块中创建一个tempdir,并在相应的`after`块中删除它. (3认同)
  • 如果你不使用该块,你可以在完成后使用`FileUtils.remove_entry_secure dir` (2认同)
  • @DavidMoles我使用的是非常严格的适合大小的定义,它与大小有关...没错,有一种情况不适合块内的执行范式(例如在测试框架内工作) (2认同)

小智 19

Dir#tmpdirRuby核心中的函数(不是您链接到的stdlib)应该是跨平台的.

要使用此功能,您需要require 'tmpdir'.

  • 这给了操作系统的全局临时路径,但不是应用程序自己专用的空路径. (4认同)
  • 同意Mike,我不认为这是对上述问题的正确答案.我们需要的是类似于Tempfile(http://ruby-doc.org/stdlib/libdoc/tempfile/rdoc/files/tempfile_rb.html),但对于dirs; 理想情况下,Tempfile直接支持dirs. (3认同)
  • `Pathname.new(Dir.tmpdir).join(SecureRandom.hex,'you_filename.txt')`? (2认同)

fgu*_*len 13

我现在正在使用的一般aprox:

def in_tmpdir
  path = File.expand_path "#{Dir.tmpdir}/#{Time.now.to_i}#{rand(1000)}/"
  FileUtils.mkdir_p path
  yield path
ensure
  FileUtils.rm_rf( path ) if File.exists?( path )
end
Run Code Online (Sandbox Code Playgroud)

所以在你的代码中你可以:

in_tmpdir do |tmpdir|
  puts "My tmp dir: #{tmpdir}"
  # work with files in the dir
end
Run Code Online (Sandbox Code Playgroud)

当您的方法完成后,临时目录自动删除.

  • 刚刚发现此行为已在[Dir.mktmpdir]中实现(http://ruby-doc.org/stdlib-1.9.3/libdoc/tmpdir/rdoc/Dir.html#method-c-mktmpdir) (7认同)
  • `Dir.mktmpdir`要好得多,因为它会使用`mkdtemp`调用,这将保证目录真正唯一.这种方法是不安全的,并且可能导致使用相同目录的两个同时运行的代码具有相同的种子,特别是因为FileUtils.mkdir_p将隐藏mkdir在目录已经存在时将抛出的错误.另外,请小心使用Dir.chdir,除非您完全确定您的进程是单线程的.如果你使用了线程网络服务器,比如Puma,你会得到一些讨厌的行为.但是对于Unicorn来说会很好. (6认同)
  • 对我来说,名称“in_tmpdir”表明“pwd”在块的上下文中发生变化。我建议使用 `Dir.chdir(path, &block)` 而不是仅仅生成路径。 (2认同)

小智 5

Ruby 有 Dir#mktmpdir,所以只需使用它。

require 'tempfile'
Dir.mktmpdir('prefix_unique_to_your_program') do |dir|
    ### your work here ###
end
Run Code Online (Sandbox Code Playgroud)

http://www.ruby-doc.org/stdlib-1.9.3/libdoc/tmpdir/rdoc/Dir.html

或者使用进程和线程唯一的 Tempfile 临时文件构建您自己的临时文件,因此只需使用它来构建快速 Tempdir。

require 'tempfile'
Tempfile.open('prefix_unique_to_your_program') do |tmp|
  tmp_dir = tmp.path + "_dir"
  begin
    FileUtils.mkdir_p(tmp_dir)

    ### your work here ###
  ensure
    FileUtils.rm_rf(tmp_dir)
  end
end
Run Code Online (Sandbox Code Playgroud)

有关可选的后缀/前缀选项,请参阅http://www.ruby-doc.org/stdlib-1.9.3/libdoc/tempfile/rdoc/Tempfile.html