4

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行时,该文件夹不包含临时文件。

4

5 回答 5

7

您确定在删除目录时 send_file 仍然没有发送文件,如果它使用 X-SendFile 可能是异步的?尝试删除目录时会导致错误。

因此,您可能应该将此删除操作排队,或者稍后使用清扫器执行此操作,而不是在将文件发送到流媒体后立即尝试执行此操作。

我不完全清楚您要发送哪个文件,因此包含文件路径和文件类型的实际示例以及如何在您的问题中创建它会很有用。

调试的可能帮助:

在执行以下操作时登录并监视文件夹:

  • 写出一个非常大的文件(> 60MB 说),并检查在您的文件创建过程中没有创建不可见的文件 - 我不清楚您实际发送的是哪个文件
  • 在慢速连接上设置大文件传输,并注意该文件的创建和可能的增长(例如,它可能与压缩动态提供的文件有关)。

鉴于当您尝试删除时 sendfile 可能仍在通过 Web 服务器发送(对于大文件)(x-send-file 现在是默认设置),我会尝试研究延迟的解决方案。

可能的解决方案:

  • 使用 send_data 而不是 send_file(如果文件很小)
  • 使用延迟作业等安排删除文件夹以供以后使用
  • 设置一个清扫器,在每天结束时删除文件夹
于 2012-11-12T22:26:52.540 回答
1

不知道为什么隐藏文件在那里,它可能是 X-send-file 甚至 wget 的分支(部分进度或其他东西)。

理想情况下,您应该使用 Tempfile 来执行此类操作。该代码基于您对您正在做的事情的评论。另外,我使用了两个 gem,一个用于下载,另一个用于压缩。这样,您根本不需要创建文件夹,只需一个 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 文档包含有关尝试删除文件/文件夹时的本地安全漏洞的详细信息。

于 2012-11-19T08:31:21.027 回答
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)
于 2016-09-16T08:59:05.963 回答
0

也许你可以试试这个解决方案:http: //info.michael-simons.eu/2008/01/21/using-rubyzip-to-create-zip-files-on-the-fly/

于 2013-04-18T22:43:36.077 回答
-1

它是如此简单但危险。使用shell命令来实现它。放进去send_file之后Controller

system ("rm -rf public/folder")
于 2012-11-21T14:34:37.390 回答