我有一个简单的sinatra应用程序需要生成一个文件(通过外部进程),将该文件发送到浏览器,最后从文件系统中删除该文件。这些方面的东西:
class MyApp < Sinatra::Base
get '/generate-file' do
# calls out to an external process,
# and returns the path to the generated file
file_path = generate_the_file()
# send the file to the browser
send_file(file_path)
# remove the generated file, so we don't
# completely fill up the filesystem.
File.delete(file_path)
# File.delete is never called.
end
end
然而,似乎send_file
调用完成了请求,并且后面的任何代码都没有运行。
有没有办法确保生成的文件在成功发送到浏览器后被清除?或者我是否需要在某个时间间隔内使用运行清理脚本的cron作业?
答案 0 :(得分:4)
不幸的是,使用send_file时没有任何回调。这里的常见解决方案是使用cron任务来清理临时文件
答案 1 :(得分:1)
您可以使用开始...确保块来清理文件:
file_path = generate_the_file()
begin
send_file(file_path)
ensure
File.delete(file_path)
end
之所以有效,是因为在Sinatra内部。 #send_file调用#halt,然后#halt调用throw :halt
。调用 throw 时,将取消堆栈堆栈,直到相应的 catch (位于Sinatra中的某个位置)为止,但是取消堆栈时,确保块运行。
答案 2 :(得分:1)
send_file 正在流式传输文件,它不是同步调用,因此您可能无法捕捉到它的结尾来清理文件。我建议将它用于静态文件或非常大的文件。对于大文件,您将需要一个 cron 作业或其他一些解决方案来稍后进行清理。您不能使用相同的方法执行此操作,因为当执行仍在 get 方法中时,send_file 不会终止。如果你真的不关心流媒体部分,你可以使用同步选项。
begin
file_path = generate_the_file()
result File.read(file_path)
#...
result # This is the return
ensure
File.delete(file_path) # This will be called..
end
当然,如果您对文件不感兴趣,您可以坚持使用 Jochem 的答案,该答案完全消除了开始-确保-结束。
答案 3 :(得分:0)
这可以是将文件内容临时存储在变量中的解决方案,例如:
contents = file.read
在此之后,删除文件:
File.delete(FILE_PATH)
最后,返回内容:
内容
这与您的send_file()
具有相同的效果。