4 Stimmen

Warum führt die Verwendung von OpenURI zum Herunterladen einer Datei zu einer Teildatei?

Ich versuche, OpenURI zu verwenden, um eine Datei von S3 herunterzuladen und sie dann lokal zu speichern, damit ich die Datei als Anlage mit ActionMailer senden kann.

Etwas Seltsames geht vor sich. Die heruntergeladenen und angehängten Bilder sind beschädigt, die unteren Teile der Bilder fehlen.

Hier ist der Code:

require 'open-uri'
open("#{Rails.root.to_s}/tmp/#{a.attachment_file_name}", "wb") do |file|  
  source_url = a.authenticated_url()
  io = open(URI.parse(source_url).to_s)
  file << io.read
  attachments[a.attachment_file_name] = File.read("#{Rails.root.to_s}/tmp/#{a.attachment_file_name}")        
end

a ist die Anlage von ActionMailer.

Was kann ich als nächstes versuchen?

9voto

the Tin Man Punkte 154584

Es sieht so aus, als ob Sie versuchen, die Datei zu lesen, bevor sie geschlossen wurde, wodurch ein Teil des Dateipuffers ungeschrieben bleiben könnte.

Ich würde es so machen:

require 'open-uri'

source_url = a.authenticated_url()
attachment_file = "#{Rails.root.to_s}/tmp/#{a.attachment_file_name}"
open(attachment_file, "wb") do |file|  
  file.print open(source_url, &:read)
end

attachments[a.attachment_file_name] = File.read(attachment_file)

Es sieht so aus source_url = a.authenticated_url() ist eine Zeichenkette, so dass das Parsen der Zeichenkette in einen URI und das anschließende to_s ist überflüssig, es sei denn, URI nimmt eine Normalisierung vor, was meines Erachtens nicht der Fall ist.

Basierend auf meiner Erfahrung als Systemadministrator: Eine Nebenaufgabe ist das Aufräumen der heruntergeladenen/gespoolten Dateien. Sie könnten sofort nach dem Anhängen gelöscht werden, oder Sie könnten einen Cron-Job einrichten, der täglich läuft und alle gespooled-Dateien löscht, die älter als ein Tag sind.

Ein zusätzliches Problem ist, dass es keine Fehlerbehandlung für den Fall gibt, dass die URL nicht gelesen werden kann, wodurch der Anhang fehlschlägt. Mit einer temporären Spooldatei könnten Sie die Existenz der Datei überprüfen. Noch besser wäre es, wenn Sie darauf vorbereitet wären, eine Ausnahme zu behandeln, wenn der Server einen 400- oder 500-Fehler zurückgibt.


Um die Verwendung einer temporären Spooldatei zu vermeiden, versuchen Sie diesen ungetesteten Code:

require 'open-uri'

source_url = a.authenticated_url()
attachments[a.attachment_file_name] = open(source_url, &:read)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X