2016-07-27 9 views
1

アプリケーションのユーザーはプレーンテキストファイルをアップロードできます。これらのファイルは、添付ファイルとして送信メールActionMailerに追加されます。最近、このメールを送信しようとしたところ、invalid byte sequence in UTF-8というエラーが発生しました。電子メールは送信されませんでした。このシンボルは、問題の添付ファイル全体に現れます。電子メールの添付ファイルに (非UTF-8文字)を無視するか、添付ファイルからそれらを削除しますか?

それは言わずに行くべきものの、我々はそうActionMailerを使用している、ここでメーラークラスのメソッド内の添付ファイルのアクションのための代表的なコードです:私たちは気にしないビジネスの観点から

attachments['file-name.jpg'] = File.read('file-name.jpg')

は、これらのテキストファイルの内容理想的には、私たちのアプリケーションがコンテンツを無視し、単にそれらを電子メールに添付したいと思っています。

何とかRails/ActionMailerに書式設定を無視することはできますか?または、UTF-8以外の文字を取り除いて、受信テキストファイルを解析する必要がありますか?

私はここでスタックオーバーフローについて質問しましたが、私が現在直面している問題は何も解決しませんでした。

編集:レールコンソールのファイルに#readlinesを呼び出して、黒い菱形が\xA0という表現であることがわかりました。これはおそらくLatin1(ISO 8859-1)の中で改行されていないスペースです。

+0

テキスト添付ファイルを読む場所(HDDやデータベースなどから)をコードに記述してください。 'str'がある時点で添付ファイルを含む文字列ならば、' str.encoding'が何であるか教えてください。文字列をメールに添付するコード行を表示します。 – AnoE

+0

これはActionMailerの電子メールにファイルを添付するための典型的なコードです: 'mail.attachments [file.file_name.to_s] = File.read(path_to_file)'。 – Tass

答えて

0

Rubyがファイルの読み取り中に文字を破損している場合は、​​を試してみてください。 あなたのファイルが既にあなたが楽しくされていない、それらを「uncorrupt」にいくつかのプロセスを見つける、またはから再符号化により使用してそれらを除去することができますいずれかの文字を破損した場合File.binreadIO

... 
    attachments['attachment.txt'] = File.binread('/path/to/file') 
... 

から継承されますASCII-8bitUTF-8無効な文字を取り除きます。

... 
    attachments['attachment.txt'] = File.binread('/path/to/file') 
    .encode('utf-8', 'binary', invalid: :replace, undef: :replace) 
... 

(。String#scrub does thisしかし、あなたがUTF-8としてそれを読み込むことができないので、あなたがそれを使用するカント)あなたの編集で

+0

提案されたソリューションを使用しても症状は変わりません。電子メールは送信されません。 '#binread'は何をすべきでしょうか?私はRuby 2.2.1の 'File'クラスのために利用可能なメソッドではありません。これは私が現在使っているものです。 – Tass

+1

'IO'から継承され、基本的に' ASCII-8bit'バイナリファイルとしてファイルを読み込みますが、ファイルにすでに壊れている文字があるようです。これはおそらく 'Base64'エンコーディングプロセスを捨ててしまいます。私は答えにもっと追加します。 – Azolo

+0

残念ながら、これも問題を解決しませんでした。そして、あなたが 'String'で利用できると言ったので、私はコンソールで'#scrub'を使用しようとしました: ''テキストテキストtext テキスト ".scrub'は' 'テキストテキストtext テキストテキスト' '(ダイヤモンド残っている、それは永続的です)。 – Tass

0

が、これは私にはかなり明確なようだ:

  1. ファイルファイルシステム上のファイルはlatin1でエンコードされています。
  2. File.readはデフォルトで標準のルビーエンコーディングを使用します。 LANGに "en_GB.utf8"のようなものが含まれている場合、File.readはその文字列をutf-8エンコーディングに関連付けます。これは、str.encodingstrの値がFile.readの場合)の値を記録することで確認できます。
  3. File.readは実際にはエンコードを検証しません。エンコードのバイトとスラップのみをスクロールします(force_encodingなど)。
  4. 後でActionMailerで何か理由で文字列を変換したいものがあり、それが期待通りに失敗する(そして気づいている)。

テキストファイルがlatin1でエンコードされている場合は、File.read(path, encoding: Encoding::ISO_8859_1)を使用してください。このようにして、動作する可能性があります。そうでない場合はお知らせください...

+0

'File.read(file).encoding'は、'# 'を出力します。' file -i 'を実行すると' charset = iso-8859-1'となります。あなたの提案したコードがうまくいかず、電子メールはまだ送信されません。しかし、それがうまくいっても、私はアップロードされた文書を制御できないので、私はそれを解決策として使用できませんでした。私が最初に言及したように、理想的には私たちのアプリケーションは単にこれらのファイルの内容を無視します。 – Tass

+0

私は本当に助けに感謝しています! – Tass

+0

もちろん、npエンコーディングは非常に混乱する問題です。ルビの "バイナリ"に最も近いのは、私が知っている限り、 'Encoding :: ASCII_8BIT'です(これはエンコーディング' binread'があなたに与えるものです)。しかし、あなたがすでにテストしたように、それもうまくいかないようです。 'ActionMailer'がバイトを' utf-8'として扱うことを主張し、エンコーディングをトランスコードまたは検証しようとする場所を見つけなければなりません。私はなぜそれが起こるのか混乱していると認めますが、私はあなたのコードが 'ActionMailer'文書からまっすぐに切り取られ、そこではPNGを転送するためにそのコードを使用することを意味します(それ以上のバイナリは得られません...)。 – AnoE

0

添付ファイルを読むときに、次の構文を使用できます。

mail.attachments[file.file_name.to_s] = File.read(path_to_file).force_encoding("BINARY").gsub(0xA0.chr,"") 

重要な追加はFile.read(...)を呼び出した後になりた、以下の通りです:ストリッピングとエンコーディングは、私たちのシステムへのファイルのアップロード時に行われるべきであるので、この

.force_encoding("BINARY").gsub(0xA0.chr,"")

答えは解決ではありません。それは短期的なバンドエイドです。

関連する問題