In Ruby on Rails, After send_file method delete the file from server

匿名 (未验证) 提交于 2019-12-03 01:52:01

问题:

I am using following code for sending the file in Rails.

 if File.exist?(file_path)   send_file(file_path, type: 'text/excel')    File.delete(file_path) end 

In this I am trying to send the file and delete the file from server once it is been send successfully. But I am facing issue is, the delete operation is getting executed while sending is performing and due to that I don't see anything in browser.

So is there any way in Rails, once the send_file operation is completed delete the file from server.

Any help on this would be highly appreciated.

Thanks,
Chetan

回答1:

Because you're using send_file, Rails will pass the request along to your HTTP server (nginx, apache, etc. - See the Rails documentation on send_file regarding X-Sendfile headers). Because of this, when you try to delete the file, Rails doesn't know that it's still being used.

You can try using send_data instead, which will block until the data is sent, allowing your File.delete request to succeed. Keep in mind that send_data requires a data stream as its argument though, not a path, so you need to open the file first:

File.open(file_path, 'r') do |f|   send_data f.read, type: "text/excel" end File.delete(file_path) 

The other option would be a background job that periodically checks for temp files to delete.



回答2:

If you are generating on the fly the file you are trying to send, a solution is to use the Tempfile class:

begin   # The second argument is optional:   temp_file = Tempfile.new(filename, temp_directory)    # ... edit temp_file as needed.    # By default, temp files are 0600,   # so this line might be needed depending on your configuration:   temp_file.chmod(0644)   send_file temp_file ensure   temp_file.close end 

Contrary to what is indicated in this question, this works as expected (the file stays on the server long enough to be served, but ultimately gets deleted); this post seems to indicate this is due to updates in Rails 3.2.11, something I couldn’t verify.



回答3:

This works for me! With send_data you can delete file before send.

file = File.open(Rails.root.join('public', 'uploads', filename), "rb") contents = file.read file.close  File.delete(filepath) if File.exist?(filepath)  send_data(contents, :filename => filename) 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!