Подтвердить что ты не робот

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

Каким образом можно безопасно удалять этот временный файл? Благодаря

4b9b3361

Ответ 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, который затем будет реагировать быстрее.