Class | Tempfile |
In: |
lib/tempfile.rb
|
Parent: | DelegateClass(File) |
A class for managing temporary files. This library is written to be thread safe.
MAX_TRY | = | 10 |
Creates a temporary file of mode 0600 in the temporary directory whose name is basename.pid.n and opens with mode "w+". A Tempfile object works just like a File object.
If tmpdir is omitted, the temporary directory is determined by Dir::tmpdir provided by ‘tmpdir.rb’. When $SAFE > 0 and the given tmpdir is tainted, it uses /tmp. (Note that ENV values are tainted by default)
# File lib/tempfile.rb, line 24 def initialize(basename, tmpdir=Dir::tmpdir) if $SAFE > 0 and tmpdir.tainted? tmpdir = '/tmp' end lock = nil n = failure = 0 begin Thread.critical = true begin tmpname = File.join(tmpdir, make_tmpname(basename, n)) lock = tmpname + '.lock' n += 1 end while @@cleanlist.include?(tmpname) or File.exist?(lock) or File.exist?(tmpname) Dir.mkdir(lock) rescue failure += 1 retry if failure < MAX_TRY raise "cannot generate tempfile `%s'" % tmpname ensure Thread.critical = false end @data = [tmpname] @clean_proc = Tempfile.callback(@data) ObjectSpace.define_finalizer(self, @clean_proc) @tmpfile = File.open(tmpname, File::RDWR|File::CREAT|File::EXCL, 0600) @tmpname = tmpname @@cleanlist << @tmpname @data[1] = @tmpfile @data[2] = @@cleanlist super(@tmpfile) # Now we have all the File/IO methods defined, you must not # carelessly put bare puts(), etc. after this. Dir.rmdir(lock) end
If no block is given, this is a synonym for new().
If a block is given, it will be passed tempfile as an argument, and the tempfile will automatically be closed when the block terminates. In this case, open() returns nil.
# File lib/tempfile.rb, line 167 def open(*args) tempfile = new(*args) if block_given? begin yield(tempfile) ensure tempfile.close end nil else tempfile end end
Closes and unlinks the file.
# File lib/tempfile.rb, line 102 def close! _close @clean_proc.call ObjectSpace.undefine_finalizer(self) end
Opens or reopens the file with mode "r+".
# File lib/tempfile.rb, line 75 def open @tmpfile.close if @tmpfile @tmpfile = File.open(@tmpname, 'r+') @data[1] = @tmpfile __setobj__(@tmpfile) end
Unlinks the file. On UNIX-like systems, it is often a good idea to unlink a temporary file immediately after creating and opening it, because it leaves other programs zero chance to access the file.
# File lib/tempfile.rb, line 112 def unlink # keep this order for thread safeness begin File.unlink(@tmpname) if File.exist?(@tmpname) @@cleanlist.delete(@tmpname) @data = @tmpname = nil ObjectSpace.undefine_finalizer(self) rescue Errno::EACCES # may not be able to unlink on Windows; just ignore end end