我使用file.txt
从我的Rails控制器发送文件send_file
,然后删除包含它的文件夹。
send_file("#{Rails.root}/public/folder/file.txt")
FileUtils.remove_dir "#{Rails.root}/public/folder", true
当我这样做时,file.txt
已被发送并删除。但是,folder
未被删除。但是,如果我删除send_file
行,则会删除folder
。
如何删除folder
?
编辑:有趣的是,我发现在folder
内有一个名为.__afs2B0C
的隐藏文件,可能会阻止删除。我不知道这个文件是如何创建的!该文件仅在大约15分钟后才会消失。
EDIT2:我尝试用vi
检查临时文件的内容,但这是不可读的乱码。当我仅删除send_file
行时,该文件夹已被正确删除。当我只删除FileUtils.remove_dir
行时,该文件夹不包含临时文件。
答案 0 :(得分:7)
您是否确定在删除目录时send_file仍未发送文件,如果它使用X-SendFile,它可能是异步的?这会在尝试删除目录时导致错误。
所以你应该排队这个删除操作,或者稍后用扫地机进行排队,而不是在将文件发送到流媒体后直接尝试。
我不清楚您要发送哪个文件,因此包含文件路径的实际示例,文件类型以及如何在您的问题中创建文件将非常有用。
可能有关调试的帮助:
执行以下操作时登录并监控文件夹:
鉴于sendfile可能仍在通过Web服务器发送(对于大文件)(x-send-file现在是默认值),当您尝试删除时,我会尝试查看延迟解决方案。
可能的解决方案:
答案 1 :(得分:1)
不确定为什么隐藏文件存在,它可能是X-send-file的分支,甚至是wget(部分进度或其他)的分支。
理想情况下,您应该使用Tempfile来执行此类操作。代码基于您对您正在做的事情的评论。另外,我使用两个宝石一个用于下载,另一个用于压缩。 这样,您根本不需要创建文件夹,只需要一个zip文件。 zip的所有内容文件将自行删除。下载zip后,只需将其删除即可。在这里我还要提一下,你可能会遇到一个小问题,因为send_file会将传输移交给网络服务器,因此你不会让rails进程在仍然被服务时删除文件。所以即使有这个,并且它在localhost上运行良好,我强烈建议在生产中使用自定义的预定背景垃圾收集器。
require 'open-uri'
require 'zip/zip'
zip_path = "#{Rails.root}/public/test.zip"
urls_to_fetch = ['abc.com', 'xyz.com']
Zip::ZipFile.open(zip_path, Zip::ZipFile::CREATE) do |zipfile|
urls_to_fetch.each_with_index do |url, index|
# intialize new temp file
file = Tempfile.new(index.to_s)
# fetch the file using open-uri or wget and save it as a tmpfile
open(url, 'rb') do |read_file|
file.write(read_file.read)
end
end
# add the temp file to the list of files to zip
zipfile.add(File.basename(file), file.path)
end
# send the zipfile for download
send_file zip_path
# delete the zipfile
FileUtils.rm zip_path
但是,这不应该是强制性的。如果你正在做没有Tempfiles的事情,请检查rails runner在目标目录上的权限。
FileUtils文档包含有关尝试删除文件/文件夹时本地安全漏洞的详细信息。
答案 2 :(得分:1)
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)
答案 3 :(得分:0)
也许你可以尝试这个解决方案: http://info.michael-simons.eu/2008/01/21/using-rubyzip-to-create-zip-files-on-the-fly/
答案 4 :(得分:-1)
send_file
中Controller
之后
system ("rm -rf public/folder")