Rails как удалить файл без сбоев при ошибке
Я использую JPEGCAM, чтобы позволить пользователям снимать профиль с помощью веб-камеры. Это загружает временный файл следующим образом:
def ajax_photo_upload
File.open(upload_path, 'w:ASCII-8BIT') do |f|
f.write request.raw_post
end
# @user.photo = File.open(upload_path)
@user.assign_attributes(
:photo => File.open(upload_path),
:orig_filename => "#{current_user.full_name}.jpg"
)
if @user.save
respond_to do |format|
.....
private
def upload_path # is used in upload and create
file_name = session[:session_id].to_s + '.jpg'
File.join(::Rails.root.to_s, 'public', 'temp', file_name)
end
Каким образом можно безопасно удалять этот временный файл? Благодаря
Ответы
Ответ 1
Когда вы знаете, что вы закончили с файлом:
File.delete(path_to_file) if File.exist?(path_to_file)
Другое дело: убедитесь, что вы всегда закрываете открытые файлы, операционная система может обрабатывать определенное количество открытых файлов/файловых дескрипторов, и вы можете столкнуться с странными ошибками при прохождении этого предела... Поэтому, когда вы хотите открывать файлы в Ruby, всегда используйте форму блока:
File.open(path) do |f|
# ...
end
и Ruby автоматически закроет файл для вас. Если форма блока недоступна, вы должны сами закрыть файлы:
f = File.open(path)
# ...
f.close
Поэтому не забудьте закрыть файл, который вы передаете в @user.assign_attributes(...)
...
Ответ 2
Если вы уверены, что с ним все закончилось, почему бы просто не использовать FileUtils.rm
или FileUtils.rm_f
?
FileUtils.rm_f(upload_path)
http://www.ruby-doc.org/stdlib-1.9.3/libdoc/fileutils/rdoc/FileUtils.html#method-c-rm_f
Вы также можете игнорировать это в Rails и иметь cron, который просыпается и удаляет файлы старше дня из каталога temp, которые соответствуют этим временным файлам. Это может привести к некоторому краю ошибки, если файл не может быть повторно обработан - вы не сразу это сделаете - и операция файла не выполняется в цикле запроса/ответа для Rails, который затем будет реагировать быстрее.