Working with temp files in Ruby

Temp files are necessary in cases when you need to store some data before feeding it into another program. In this post, I am going to show you several ways of creating temp files and how to use them in Ruby code.

Temp files or temporary files are files created at a certain moment and then no longer needed. Imagine that you are developing a program to convert accept an HTML text from users and then convert it into a PDF file. For this purpose, you want to use the tool wkhtmltopdf (http://wkhtmltopdf.org/), which runs as a stand-alone command after installation. The usage of wkhtmltopdf command is like this:

wkhtmltopdf test.html output.pdf

Because you cannot pass the whole HTML text directly to this command, you have to temporarily store the HTML text into a temp file and run this command against that file.

The first naive solution is to save the HTML text to a file at a specific location in your program folder, run wkhtmltopdf, and then delete it from the disk manually.

# create the temp file
f = File.open("mytempfile.html", "w")
f.write(html_text)
f.close

# run wkhtmltopdfhere
# wkhtmltopdf mytempfile.html output.pdf

# delete the temp file
File.delete("mytempfile.html")

An obvious issue with this solution is that we need to specify the name of the tempfile so that it would not overwrite the content of other files (in environments with co-current users), and we have to manually delete it after using it.

Another method is to create a file inside /tmp folder of your system. This special folder is automatically cleaned by the system and a lot of programs use it, so we can use it too.

# create the temp file
f = File.open("/tmp/mytempfile.html", "w")
f.write(html_text)
f.close

# run wkhtmltopdf here
# wkhtmltopdf mytempfile.html output.pdf

Do you see the difference? We are creating a file inside /tmp folder and no longer need to delete the file after using it. But we still have to specify the name of the file and make sure it is not the same with other files. One enhancement will be like this:

# create the temp file
# generate random string as file name
rand_string = (0...8).map { (65 + rand(26)).chr }.join
f = File.open("/tmp/{rand_string}.html", "w")
f.write(html_text)
f.close

# run wkhtmltopdf here
# wkhtmltopdf mytempfile.html output.pdf

Now, even though the code looks better, we should ask why we even need to specify the name of a tempfile. We only use this file once and never pay attention to it again so it is better if the program is smart enough to generate a random file name for us as well. That's when Tempfile (http://apidock.com/ruby/Tempfile) comes into play. Here is the code when using tempfile in Ruby:

require 'tempfile'

file = Tempfile.new('test')
file.write(html_string)
file.close

# run wkhtmltopdf here, use file.path
# wkhtmltopdf <file.path here> output.pdf

file.unlink

The name we provided in the constructor of Tempfile is only the base name, and Tempfile will automatically add a random string after our specified name. In addition, when running wkhtmltopdf command, we should refer to the temp file by using the method file.path. By doing this, we can be sure that the temp file created will be unique and it will be deleted by the system automatically. However in practice, it is recommended to explicitly delete the file by calling file.unlink.

Temp files are often used in many applications therefore almost all programming languages support it. You can find it in Python, Java, C#, etc. Be sure to use it when needed to create a high-quality code.

Happy coding!