非常教程

Ruby 2.4参考手册

临时文件 | Tempfile

Tempfile

Parent:DelegateClass(File)

用于管理临时文件的实用程序类。当您创建一个Tempfile对象时,它将创建一个具有唯一文件名的临时文件。Tempfile对象的行为与File对象相似,您可以对其执行所有常见的文件操作:读取数据,写入数据,更改权限等。因此,尽管此类不明确记录File支持的所有实例方法,但您实际上可以调用Tempfile对象上的任何File实例方法。

概要

require 'tempfile'

file = Tempfile.new('foo')
file.path      # => A unique filename in the OS's temp directory,
               #    e.g.: "/tmp/foo.24722.0"
               #    This filename contains 'foo' in its basename.
file.write("hello world")
file.rewind
file.read      # => "hello world"
file.close
file.unlink    # deletes the temp file

好的做法

显式关闭

当一个Tempfile对象被垃圾收集时,或者当Ruby解释器退出时,其相关的临时文件将被自动删除。这意味着在使用后没有必要显式删除一个临时文件,尽管这样做很好:不明确地删除未使用的临时文件可能会在文件系统上留下大量的临时文件,直到它们被垃圾收集为止。这些临时文件的存在可能会导致难以确定新的Tempfile文件名。

因此,应该始终在确保块中调用取消链接或关闭,如下所示:

file = Tempfile.new('foo')
begin
   ...do something with file...
ensure
   file.close
   file.unlink   # deletes the temp file
end

创建后取消链接

在POSIX系统上,可以在创建文件之后以及关闭文件之前解除文件的链接。这会在不关闭文件句柄的情况下删除文件系统条目,因此它确保只有已打开文件句柄的进程才能访问文件内容。强烈建议您如果不希望任何其他进程能够读取或写入Tempfile,并且不需要知道Tempfile的文件名,则可以执行此操作。

例如,创建unlink-after-a的实际用例是这样的:你需要一个大的字节缓冲区,这个缓冲区太大而不适合放在RAM中,例如,当你正在编写web服务器并且你想要缓冲客户端的文件上传时数据。

请参阅取消链接了解更多信息和代码示例。

次要笔记

Tempfile的文件名选取方法既是线程安全的也是进程间安全的:它保证没有其他线程或进程会选择相同的文件名。

Tempfile本身可能并不完全是线程安全的。如果你从多个线程访问同一个Tempfile对象,那么你应该用一个互斥锁来保护它。

公共类方法

create(basename="", tmpdir=nil, mode: 0, **options) { |tmpfile| ... } 显示源

像平常一样创建一个临时文件File对象(不是Tempfile)。它不使用终结器和委托。

如果没有给出块,除了创建File而不是Tempfile之外,它与:: new类似。创建的文件不会自动删除。您应该使用File.unlink将其删除。

如果给出了一个块,那么将构造一个File对象,并将该对象作为参数调用该块。File对象将自动关闭,并在块终止后删除临时文件。该调用返回该块的值。

无论如何,所有参数(+ * args +)都将被视为:: new。

Tempfile.create('foo', '/home/temp') do |f|
   ... do something with f ...
end
# File lib/tempfile.rb, line 325
def Tempfile.create(basename="", tmpdir=nil, mode: 0, **options)
  tmpfile = nil
  Dir::Tmpname.create(basename, tmpdir, options) do |tmpname, n, opts|
    mode |= File::RDWR|File::CREAT|File::EXCL
    opts[:perm] = 0600
    tmpfile = File.open(tmpname, mode, opts)
  end
  if block_given?
    begin
      yield tmpfile
    ensure
      tmpfile.close
      File.unlink tmpfile
    end
  else
    tmpfile
  end
end

new(basename = "", tmpdir = Dir.tmpdir, options) 显示源

创建一个权限为0600(=只能由所有者读写)的临时文件,并使用模式“w +”打开它。

basename参数用于确定临时文件的名称。您可以传递一个String或一个包含2个String元素的数组。在前一种形式中,临时文件的基本名称将以给定的字符串开头。在后一种形式中,临时文件的基本名称将从数组的第一个元素开始,并以第二个元素结束。例如:

file = Tempfile.new('hello')
file.path  # => something like: "/tmp/hello2843-8392-92849382--0"

# Use the Array form to enforce an extension in the filename:
file = Tempfile.new(['hello', '.jpg'])
file.path  # => something like: "/tmp/hello2843-8392-92849382--0.jpg"

临时文件将被放置在tmpdir参数指定的目录中。默认情况下,这是Dir.tmpdir。当$ SAFE> 0且给定tmpdir被污染时,它使用'/ tmp'作为临时目录。请注意,ENV值默认情况下被污染,并且Dir.tmpdir返回值可能来自环境变量(例如$TMPDIR)。

file = Tempfile.new('hello', '/home/aisaka')
file.path  # => something like: "/home/aisaka/hello2843-8392-92849382--0"

您也可以传递选项散列。在引擎盖下,Tempfile使用创建临时文件File.open。这些选项将被传递给File.open。这对于指定编码选项非常有用,例如:

Tempfile.new('hello', '/home/aisaka', :encoding => 'ascii-8bit')

# You can also omit the 'tmpdir' parameter:
Tempfile.new('hello', :encoding => 'ascii-8bit')

例外

如果:: new在有限次数的尝试中找不到唯一的文件名,则会引发异常。

调用超类方法

# File lib/tempfile.rb, line 125
def initialize(basename="", tmpdir=nil, mode: 0, **options)
  warn "Tempfile.new doesn't call the given block." if block_given?

  @unlinked = false
  @mode = mode|File::RDWR|File::CREAT|File::EXCL
  ::Dir::Tmpname.create(basename, tmpdir, options) do |tmpname, n, opts|
    opts[:perm] = 0600
    @tmpfile = File.open(tmpname, @mode, opts)
    @opts = opts.freeze
  end
  ObjectSpace.define_finalizer(self, Remover.new(@tmpfile))

  super(@tmpfile)
end

open(*args) { |tempfile| ... }显示源

创建一个新的Tempfile。

如果没有给出块,这是:: new的同义词。

如果给出了一个块,那么将构造一个Tempfile对象,并且该块以所述对象作为参数运行。Tempfile对象将在块终止后自动关闭。该调用返回该块的值。

无论如何,所有参数(+ * args +)都会被传递给:: new。

Tempfile.open('foo', '/home/temp') do |f|
   ... do something with f ...
end

# Equivalent:
f = Tempfile.open('foo', '/home/temp')
begin
   ... do something with f ...
ensure
   f.close
end
# File lib/tempfile.rb, line 289
def open(*args)
  tempfile = new(*args)

  if block_given?
    begin
      yield(tempfile)
    ensure
      tempfile.close
    end
  else
    tempfile
  end
end

公共实例方法

close(unlink_now=false)显示源

关闭文件。如果unlink_now为真,那么文件在关闭后将被取消链接(删除)。当然,如果你现在不解除链接,你可以选择稍后调用unlink。

如果您没有明确取消临时文件的链接,则删除操作将延迟到对象完成时为止。

# File lib/tempfile.rb, line 159
def close(unlink_now=false)
  _close
  unlink if unlink_now
end

close!() 显示源

关闭并取消链接(删除)文件。具有与所谓的相同的效果close(true)

# File lib/tempfile.rb, line 166
def close!
  close(true)
end

delete()

别名为:取消链接

length()

别名为:大小

open() 显示源

打开或重新打开模式为“r +”的文件。

# File lib/tempfile.rb, line 141
def open
  _close
  mode = @mode & ~(File::CREAT|File::EXCL)
  @tmpfile = File.open(@tmpfile.path, mode, @opts)
  __setobj__(@tmpfile)
end

path() 显示源

返回临时文件的完整路径名称。如果取消链接被调用,这将是零。

# File lib/tempfile.rb, line 219
def path
  @unlinked ? nil : @tmpfile.path
end

size() 显示源

返回临时文件的大小。作为副作用,IO缓冲区在确定大小之前被刷新。

# File lib/tempfile.rb, line 225
def size
  if !@tmpfile.closed?
    @tmpfile.size # File#size calls rb_io_flush_raw()
  else
    File.size(@tmpfile.path)
  end
end

另外别名为:长度

unlink() 显示源

从文件系统取消链接(删除)文件。在使用该文件后,应始终取消链接,如Tempfile概述中的“显式关闭”良好实践部分中所述:

file = Tempfile.new('foo')
begin
   ...do something with file...
ensure
   file.close
   file.unlink   # deletes the temp file
end

取消链接 - 前关闭

在POSIX系统上,可以在关闭文件之前取消链接。Tempfile概述中详细介绍了这种做法(“创建后取消链接”一节); 请参阅那里获取更多信息。

但是,非POSIX操作系统可能不支持unlink-before-close。Microsoft Windows是最值得关注的案例:取消关闭非关闭文件将导致错误,该方法将默默忽略。如果你想尽可能练习unlink-before-close,那么你应该写下如下代码:

file = Tempfile.new('foo')
file.unlink   # On Windows this silently fails.
begin
   ... do something with file ...
ensure
   file.close!   # Closes the file handle. If the file wasn't unlinked
                 # because #unlink failed, then this method will attempt
                 # to do so again.
end
# File lib/tempfile.rb, line 203
def unlink
  return if @unlinked
  begin
    File.unlink(@tmpfile.path)
  rescue Errno::ENOENT
  rescue Errno::EACCES
    # may not be able to unlink on Windows; just ignore
    return
  end
  ObjectSpace.undefine_finalizer(self)
  @unlinked = true
end

另外别名为:删除

临时文件 | Tempfile相关

Ruby 2.4

Ruby 是一种面向对象、命令式、函数式、动态的通用编程语言,是世界上最优美而巧妙的语言。

主页 https://www.ruby-lang.org/
源码 https://github.com/ruby/ruby
版本 2.4
发布版本 2.4.1

Ruby 2.4目录

1.缩略 | Abbrev
2.ARGF
3.数组 | Array
4.Base64
5.基本对象 | BasicObject
6.基准测试 | Benchmark
7.BigDecimal
8.绑定 | Binding
9.CGI
10.类 | Class
11.比较 | Comparable
12.负责 | Complex
13.计算续体 | Continuation
14.覆盖 | Coverage
15.CSV
16.日期 | Date
17.日期时间 | DateTime
18.DBM
19.代理 | Delegator
20.摘要 | Digest
21.Dir
22.DRb
23.编码 | Encoding
24.枚举 | Enumerable
25.枚举 | Enumerator
26.ENV
27.ERB
28.错误 | Errors
29.Etc
30.期望值 | Exception
31.错误类 | FalseClass
32.Fiber
33.Fiddle
34.文件 | File
35.文件实用程序 | FileUtils
36.查找 | Find
37.浮点 | Float
38.Forwardable
39.GC
40.GDBM
41.GetoptLong
42.Hash
43.Integer
44.IO
45.IPAddr
46.JSON
47.Kernel
48.语言 | 3Language
49.记录 | Logger
50.编排 | Marshal
51.MatchData
52.数学 | Math
53.矩阵 | Matrix
54.方法 | Method
55.模型 | Module
56.监控 | Monitor
57. 互斥 | Mutex
58.Net
59.Net::FTP
60.Net::HTTP
61.Net::IMAP
62.Net::SMTP
63.NilClass
64.数字 | Numeric
65.对象 | Object
66.ObjectSpace
67.Observable
68.Open3
69.OpenSSL
70.OpenStruct
71.OpenURI
72.OptionParser
73.路径名 | Pathname
74.完整输出 | PrettyPrint
75.Prime
76.Proc
77.过程 | Process
78.PStore
79.PTY
80.队列 | Queue
81.随机 | Random
82.范围 | Range
83.合理的 | Rational
84.Readline
85.Regexp
86.Resolv
87.Ripper
88.RubyVM
89.Scanf
90.SDBM
91.SecureRandom
92.Set
93.Shell
94.信号 | Signal
95.Singleton
96.套接字 | Socket
97.字符串 | String
98.StringIO
99.StringScanner
100.结构 | Struct