Topic: Delete file after send_file is done

Hello,

I have a file server which has to be deleted after a user downloads it. I send the file with send_file, but I can't just put a File.delete(path) after that line because send_file returns immediatly, so the file is deleted even before the user receives the complete file.

How do I fix this? I think it's a common problem but haven't found a solution yet.

Thanks!

Re: Delete file after send_file is done

have the same issue, would me nice to see some example

Re: Delete file after send_file is done

This is not really the best fix, but what you could do is track when these files were sent to the users using a model (eg. FileLog table), and run a scheduled rake task that would delete these files a set time delay after the date the files were logged.

Now if you have large files, you'll have to factor that into your consideration when selecting a delay.

Again, not the best solution, but A solution nonetheless. 

I'm curious how others are doing this.

Last edited by phester (2008-06-04 17:44:52)

Re: Delete file after send_file is done

Someone had the same problem here:
http://groups.google.com/group/rubyonra … 20acd9dcd2

Seemse like there is no 'elegant' solution to this and that the files indeed will have to be removed by some external 'force'.

Thanks for your replies though!

Re: Delete file after send_file is done

My site has a download section.

For my application I only allow one user into the download section at a time.

When the user requests the file I delete the previous download. That keeps the download section clean.

Not sure if that solution would work for you.

Scott

Re: Delete file after send_file is done

i'm new to rails so i could be wrong here...but can't you use a callback to do this?


i copied this from a book i purchased. hope it helps:

class Order < ActiveRecord::Base
  # ..
  def before_save
    self.payment_due ||= Time.now + 30.days
  end
end

this is the more common form i've seen on the web too:
class Order < ActiveRecord::Base
  before_validation :normalize_credit_card_number

  after_create do |order|
    logger.info "Order #{order.id} created"
  end

  protected
  def normalize_credit_card_number
    self.cc_number.gsub!(/[-\s]/, '' )
  end
end


hope that helps.

Re: Delete file after send_file is done

As far as I know there is no callback for send_file, but while checking this I found the solution for this problem. There is an send_file option:
:stream - whether to send the file to the user agent as it is read (true) or to read the entire file before sending (false). Defaults to true.

When U set :strem => false U can delete the file just after send_file return.

God bless U.

Re: Delete file after send_file is done

I know this is a semi-old post, but I'll add my two cents for people looking at this later...

Could you use the Tempfile class and let Ruby's garbage collection do it for you?

tmp_file = Tempfile.new(Digest::MD5.hexdigest(rand(12).to_s))
Prawn::Document.generate(tmp_file.path()) do |pdf|
  ...
  #prawn stuff here
end

send_file tmp_file.path,
              :content_type => "application/pdf",
              :filename => "#{somename}.pdf"

That way when the program completes it deletes the Tempfile.

Just a suggestion.

Re: Delete file after send_file is done

hii,As i also need to implement my rails application in the same way.I have a file server which has to be deleted after a user downloads it. I send the file with send_file, but I can't just put a File.delete(path) after that line because send_file returns immediatly, so the file is deleted even before the user receives the complete file.Here is my code below:

def export_rawdata
  @device = Device.find_by_id( params[:id] )
  @messages = @device.devmessages.all( :order => "id", :conditions => ["packettime >= ? and packettime <= ?", params[:start_time], params[:end_time]] )
  raw_data_path = "#{Rails.root}/tmp/exports/#{@device.s_dev_name}.csv"
 
  FasterCSV.open(raw_data_path, "w+") do |csv|
    csv << ["Packet","Created At"]
    @messages.each_with_index do |m,i|
     x = m.created_at
     csv << [m.message, x.strftime('%h %d, %G %r')]
    end
  end
 
  send_file raw_data_path, :type => "text/csv", :x_sendfile => true, :streaming => false
 
end

Can Anyone plz suggest me, how to delete a file from the server once the download is completed in the client side?

Last edited by shonalineha (2011-12-16 01:26:35)

Re: Delete file after send_file is done

Use Ruby's IO class popen method

IO.popen ('rm -r $RELATIVEPATHTOFILE') { |f| puts 'DELETED' }