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

X-SendFile を使用している場合、send_file はディレクトリを削除しているときにまだファイルを送信していませんか? ディレクトリを削除しようとすると、エラーが発生します。

したがって、ファイルをストリーミングに送信した直後に実行しようとするのではなく、おそらくこの削除アクションをキューに入れるか、後でスイーパーで実行する必要があります。

あなたが送信しているファイルについて完全に明確ではないため、ファイルパス、ファイルタイプ、およびファイルの作成方法の実際の例を質問に含めると便利です。

デバッグで可能なヘルプ:

次のアクションを実行しながら、ログインしてフォルダを監視します。

  • 非常に大きなファイル (> 60MB と言う) を書き出し、ファイル作成プロセス中に作成された目に見えないファイルがないことを確認します - 実際に送信しているファイルは明確ではありません
  • 低速の接続で大きなファイル転送を設定し、このファイルの作成と拡大に注意してください (たとえば、オンザフライで提供されるファイルの圧縮に関連している可能性があります)。

削除しようとしたときに sendfile がまだ Web サーバー経由で (大きなファイルの場合) 送信している可能性があることを考えると (現在は x-send-file がデフォルトです)、遅延した解決策を調べてみます。

可能な解決策:

  • send_file ではなく send_data を使用する (ファイルが小さい場合)
  • delay_job のようなものを使用して、後でフォルダーの削除をスケジュールします。
  • 毎日の終わりにフォルダーを削除するスイーパーを設定します
于 2012-11-12T22:26:52.540 に答える
1

その隠しファイルがそこにある理由がわからない場合は、X-send-fileまたはwget(部分的な進行状況など)の派生物である可能性があります。

理想的には、Tempfileを使用してこのようなことを行う必要があります。コードは、あなたがしていることについてのあなたのコメントに基づいています。また、ダウンロード用と圧縮用の2つのgemを使用しています。このように、フォルダを作成する必要はまったくなく、zipファイルを直接作成するだけです。zipのすべてのコンテンツファイルは自動的に削除されます。zipをダウンロードしたら、削除してください。ここでも、send_fileが転送をWebサーバーに引き渡すため、どこかでグリッチが発生する可能性があることにも言及する必要があります。そのため、ファイルがまだ提供されている間は、ファイルを削除するためのRailsプロセスは実行されません。したがって、これがあり、ローカルホストでうまく機能している場合でも、本番環境でカスタムのスケジュールされたバックグラウンドガベージコレクターを使用することを強くお勧めします。

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

ただし、これは必須ではありません。Tempfileを使用せずに作業を行っている場合は、railsrunnerがターゲットディレクトリに対して持っている権限を確認してください。

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

とてもシンプルですが危険です。それを達成するためにシェルコマンドを使用してください。後send_fileに入れてController

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