About Tempfile

In video controller, create action. I am using FFMPEG to generate a thumbnail of videos that are uploaded.

The tempfile is created as such:

def create   ......   dst = Tempfile.new(basename)   dst.binmode

  system("ffmpeg -itsoffset -4 -i #{file.path} -y -vcodec mjpeg - vframes 1 -an -f rawvideo #{File.expand_path(dst.path)}.png")   .... end

As you can see from above, ffmpeg outputs a file to the var dst which is an instance of Tempfile. In console, when I do:

ls /var/folders/uL/uL0bYOOZEZaJH5E+BmDJVE+++TI/-Tmp-/

thumb20101111-989-1gflwhr.png thumb20101111-989-1pt72my.png thumb20101111-989-kjcsgd.png thumb20101111-989-3ocf15.png thumb20101111-989-10azwnn.png thumb20101111-989-7x11w7.png

I see a bunch of files in the directory. It seems that rails did not automatically delete these temp files. Should I manually delete these files?

I am worried that, if my temp dir fills up with temp files, it'll eventually take up most of the server space...

Your thoughts on this matter?

When you close the Tempfile, be sure to pass true for unlink_now.

Hi Brian,

Just to keep things clear. By the end of the day, /var/folders/uL/ uL0bYOOZEZaJH5E+BmDJVE+++TI/-Tmp-/ <-- temp dir _IS_ supposed to be empty. Is this correct?

Hi Christian,

Not by the end of the day, no. Each tempfile will be unlinked as soon as you close it. Your example code didn't have the line

dst.close(unlink_now=true)

in it. You may also use dst.close!() to the same effect.

Ok that makes sense. Thanks Brian.

On the same topic...

How would I create a temp file with .png extension in the end.

tmp = Tempfile.new([ 'thumb', 'png' ].compact.join("."))

Whenever it creates a temp file, it creates it as such: thumb.png20101111-989-1pt72my, instead of thumb20101111-989-1pt72my.png

If I try to save this via Active Record, with

@video.attachment_thumbnail = File.open("#{File.expand_path(tmp.path)}"),

It will save the file in the file system without the extension, which makes it impossible to read on the browser, unless I explicitly set the extension.

I'm confused. You're creating a tempfile and then keeping a reference to it in your database?

Ok that makes sense. Thanks Brian.

On the same topic...

How would I create a temp file with .png extension in the end.

tmp = Tempfile.new([ 'thumb', 'png' ].compact.join("."))

You can't use Tempfile to do this. Well, you _can_ but you'll need to close the file--without unlinking it!--and then move the file created to the new location you want. At that points, you're better off just giving thumbnails a sequential identifier, or use their hash. Destroy the thumbnail file once you no longer need it.

No, the following saves the temp file.

@video.attachment_thumbnail = File.open(File.expand_path(tmp.path))

However, File.expand_path(tmp.path) saves the file in the file system as thumb.png20101111-989-1pt72my

Ideally, I would like it to save it as thumb20101111-989-1pt72my.png or, better, just thumb.png

Basically I need to create a new tempfile with a png extension. Is this possible?

No, the following saves the temp file.

@video.attachment_thumbnail = File.open(File.expand_path(tmp.path))

Ah, apologies.

However, File.expand_path(tmp.path) saves the file in the file system as thumb.png20101111-989-1pt72my Ideally, I would like it to save it as thumb20101111-989-1pt72my.png

Okay, so you've got this:

tmp = Tempfile.new([ 'thumb', 'png' ].compact.join("."))

The documentation for Tempfile states that .new "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." The computer is doing exactly what you tell it to do.

or, better, just thumb.png

Would not this conflict if you have multiple users uploading files at the same time?

Yes, but not with Tempfile. Hash the video data, store your thumbnail as $HASH.png, keep a reference to this file and be sure to delete it when the user performs such actions as make the thumbnail no longer necessary.

Would not this conflict if you have multiple users uploading files at

the same time?

Yea, thinking along those lines. It would conflict. So if tmp = Tempfile.new([ 'thumb', 'png' ].compact.join(".")) creates temp files as thumb.png20101111-989-1pt72my, how would I tell Active Record to save it with a .png extension, since it is a png file after all.

Remember, @video.attachment_thumbnail = File.open(File.expand_path(tmp.path)), saves the file in the file system as thumb.png20101111-989-1pt72my (raw file, no extension)

Yes, but not with Tempfile.

There wont be any conflicts?

Hash the video data, store your thumbnail as $HASH.png, keep a reference to this file

Can you give me an example of how I would $HASH a file? How do you mean "keep a reference to this file"?