问题
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)
来源:https://stackoverflow.com/questions/18232088/in-ruby-on-rails-after-send-file-method-delete-the-file-from-server