4

OpenURI を使用して S3 からファイルをダウンロードし、それをローカルに保存して、ActionMailer でファイルを添付ファイルとして送信できるようにしようとしています。

何か奇妙なことが起こっています。ダウンロードして添付した画像が破損しており、画像の下部が欠落しています。

コードは次のとおりです。

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

aActionMailer からの添付ファイルです。

次に何を試すことができますか?

4

1 に答える 1

9

ファイルが閉じられる前にファイルを読み込もうとしているようです。これにより、ファイル バッファの一部が書き込まれないままになる可能性があります。

私は次のようにします:

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)

文字列のように見えるsource_url = a.authenticated_url()ので、文字列を URI に解析してそれを実行to_sすることは、URI が何らかの正規化を行っていない限り冗長になります。

私のシステム管理者の経験に基づく: サイド タスクは、ダウンロード/スプールされたファイルをクリーンアップすることです。それらは接続された直後に削除されるか、毎日実行される cron ジョブを使用して、1 日以上経過したすべてのスプール ファイルを削除することができます。

これに関するもう 1 つの問題は、URL を読み取ることができず、添付ファイルが失敗した場合のエラー処理がないことです。一時スプール ファイルを使用すると、ファイルの存在を確認できます。さらに良いことに、サーバーが 400 または 500 エラーを返した場合に例外を処理できるように準備しておく必要があります。


一時スプール ファイルの使用を避けるには、次のテストされていないコードを試してください。

require 'open-uri'

source_url = a.authenticated_url()
attachments[a.attachment_file_name] = open(source_url, &:read)
于 2010-12-06T00:37:57.627 に答える