在Ruby on Rails中,在send_file方法之后从服务器中删除该文件

时间:2023-02-06 00:14:54

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

我使用以下代码在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.

所以在Rails中有任何方法,一旦send_file操作完成,从服务器删除文件。

Any help on this would be highly appreciated.

任何有关这方面的帮助将受到高度赞赏。

Thanks,
Chetan

谢谢,Chetan

3 个解决方案

#1


32  

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.

因为您正在使用send_file,Rails会将请求传递给您的HTTP服务器(nginx,apache等 - 请参阅有关X-Sendfile头的send_file上的Rails文档)。因此,当您尝试删除文件时,Rails不知道它仍在使用中。

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:

您可以尝试使用send_data,它将阻塞直到数据发送,从而允许您的File.delete请求成功。请记住,send_data需要数据流作为其参数,而不是路径,因此您需要先打开文件:

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


2  

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

如果您正在生成要尝试发送的文件,则解决方案是使用Tempfile类:

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.

与此问题中指出的相反,这可以按预期工作(文件在服务器上停留的时间足够长,但最终会被删除);这篇文章似乎表明这是由于Rails 3.2.11中的更新,我无法验证。

#3


1  

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

这适合我!使用send_data,您可以在发送之前删除文件。

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)

#1


32  

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.

因为您正在使用send_file,Rails会将请求传递给您的HTTP服务器(nginx,apache等 - 请参阅有关X-Sendfile头的send_file上的Rails文档)。因此,当您尝试删除文件时,Rails不知道它仍在使用中。

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:

您可以尝试使用send_data,它将阻塞直到数据发送,从而允许您的File.delete请求成功。请记住,send_data需要数据流作为其参数,而不是路径,因此您需要先打开文件:

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


2  

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

如果您正在生成要尝试发送的文件,则解决方案是使用Tempfile类:

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.

与此问题中指出的相反,这可以按预期工作(文件在服务器上停留的时间足够长,但最终会被删除);这篇文章似乎表明这是由于Rails 3.2.11中的更新,我无法验证。

#3


1  

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

这适合我!使用send_data,您可以在发送之前删除文件。

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)