Using temporary files in Ruby – Tempfile.new

For certain programming solutions, you might need a temporary file. Different operating systems store temporary files in different locations. Also you don’t want to explicitly name the file since that is irrelevant in the program. How do you ensure that there are no filename conflicts? The solution for all these is to use library for temp file processing.

Ruby comes a with a default library ‘tempfile’ for handling temporary file creation. Given a filename prefix, it creates a temporary file in the following format.

[prefix]-[process].[unique_number]

This ensures that there is no conflict in creating multiple temporary files in the same directory. Once your program terminates the temporary file is automatically deleted. Also by default, the temporary file is created in the operating system’s temporary folder (In my ubuntu system it is /tmp).

In the following program, a temporary file with prefix ‘random’ to store 50 random numbers is created. When the program terminates you cannot see the temp file. Hence I have added a ‘gets’ which stops for user input. In my case I could see a temporary file named ‘random.5789.0’ under \tmp dir.

require 'tempfile'

class TempSample

temp_file = Tempfile.new('random')
1.upto(50) do
  num = rand(50) # random number generation in ruby
  temp_file.print(num,"\n") # print number and newline to the file
end
temp_file.flush # flush it so that you can see it using cat

gets # wait for user input. At this point you can see a temp file /tmp
# The filename in my case was random.5789.0

end

If you want to the temp file in a specific directory, you can pass the directory name as the second parameter to new. For example – Tempfile.new(‘new1′,’/usr/home/jay’)

3 Responses to “Using temporary files in Ruby – Tempfile.new”

  1. Be careful. This is called insecure temporary file handling. The filename you create is predictable. Predicting the filename, an attacker can cause you to overwrite any file you have write access to, by referring to it with an appropriately named symlink.

  2. Jonas Wagner on July 9th, 2009 at 2:33 pm

    @Sheldon: It looks as if in the latest version of the Tempfile library, the filename always contains a random part. It’s still vulnerable to race conditions though because it doesn’t use an atomic test-for-existance-and-create-file-if-it-doesnt-exist, but that isn’t a portable feature of file systems I guess…

    @all: A nice, undocumented feature is that you can also set the extension of the temporary file, like this:

    temp_file = Tempfile.new([‘random’, ‘.jpg’])

  3. Sheldon, as pointed out earlier in the post using Tempfile.new(‘some_prefix’) will create a file of the format:

    $TMPDIR/some_prefix-[process].[unique_number]

    Just tried it out in IRB and this is what happens:
    >> t = Tempfile.new(‘wooot’)
    => #

    Hence this is the safe way to deal with temporary files.

    /Peter

Leave a Reply