Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any way to make a Ruby temporary file permanent?

If I've created a temporary file through Tempfile, is there any way aside from copying it to another file that I can make it "permanent"? I'd like to avoid it getting deleted when the associated Tempfile instance is garbage collected or the process is terminated.

On a related point, is there a way to leverage the Tempfile mechanism (or use a similar mechanism) to get a "new" filename without having to create a file at that name?

like image 245
Peter Alfvin Avatar asked Jan 22 '14 14:01

Peter Alfvin


People also ask

How long does a temp file last?

These temporary attachment files might need to stay around indefinitely, if the user never closes the associated application.

How do you create a temp file in Ruby?

In any case, all arguments ( basename , tmpdir , mode , and **options ) will be treated as ::new. Creates a temporary file with permissions 0600 (= only readable and writable by the owner) and opens it with mode “w+”. The temporary file will be placed in the directory as specified by the tmpdir parameter.

What is considered a temporary file?

Alternatively referred to as a foo file, a temporary file or temp file is a file created to hold information while a file's being created or modified. After the program is closed, the temporary file is deleted. Temporary files store and move data, manage settings, help recover lost data, and manage multiple users.

What creates temporary files?

What are temporary files? Temporary files, also called temp or tmp files, are created by Windows or programs on your computer to hold data while a permanent file is being written or updated. The data will be transferred to a permanent file when the task is complete, or when the program is closed.


2 Answers

Not really. For the question itself, see this:

ObjectSpace.undefine_finalizer(tmpfile) 

The Tempfile library uses Ruby ObjectSpace finalizers to automatically delete itself on garbage collection. By using the above line you can remove the Tempfile's ability to delete itself if you don't delete it. So, for example:

$ irb 2.0.0p0 :001 > require "tempfile"  => true  2.0.0p0 :002 > t = Tempfile.new("test")  => #<Tempfile:/tmp/test20140122-6655-80p4b7>  2.0.0p0 :003 > t.write("Hi!")  => 3  2.0.0p0 :004 > ObjectSpace.undefine_finalizer(t)  => #<Tempfile:/tmp/test20140122-6655-80p4b7>  2.0.0p0 :005 > exit $ cat /tmp/test20140122-6655-80p4b7 Hi! $  

There's something else to be aware of though. Tempfile will use system temporary file directories like /tmp that the OS automatically cleans out every once in a while (for example on every boot). Because of this, even if you "persist" the file, you either need to be OK with it disappearing, or move it to a directory that doesn't get cleaned out by default, like /var/tmp (the Linux directory for persistant temporary files).


As for your second question, try this code from here:

Dir::Tmpname.create('your_application_prefix') { |path| puts path } 

It requires a require "tmpdir".

like image 76
Linuxios Avatar answered Sep 29 '22 17:09

Linuxios


I think the simplest solution may be to monkey patch the Tmpfile class to add a persist method. This method takes a filename where the temporary file will be moved to. Additionally, it removes the finalizer so that the temporary file will not be deleted at exit.

require 'tempfile' require 'fileutils'  class Tempfile   def persist(filename)     FileUtils.mv(self.path, filename)     ObjectSpace.undefine_finalizer(self)   end end  file = Tempfile.new('tmp') file.write('hello world') file.close file.persist('hello.txt') 

Running this program will create a persistent file ./hello.txt by moving the original temporary file instead of copying it.

like image 22
Patrick Oscity Avatar answered Sep 29 '22 19:09

Patrick Oscity