Shift_JISのファイルをencodeしても文字化けが解消しなかったので調べてみました。
結論、force_encodingは強制変換ではなく、エンコーディング情報(文字コードが何か)を変えるだけ。エンコーディング情報を正しくしないと、encodeも正しくできない。

File.read → encode

Shift_JISのファイルを用意して、読み込み

> body = File.read('/tmp/test_sjis.txt')
 => "\x83e\x83X\x83g\r\n" 

UTF-8(LFも)に変換してみる →文字化け

> body.encode(Encoding::UTF_8, invalid: :replace, undef: :replace, universal_newline: true)
 => "�e�X�g\r\n"

encodingを確認する →UTF-8として扱われている

> body.encoding
 => #<Encoding:UTF-8>

force_encoding → encode

encodingをSJIS変更する
force_encodingはencodingを強制的に変更する(強制的にencodeする訳ではない)

> body.force_encoding(Encoding::SJIS)
 => "\x{8365}\x{8358}\x{8367}\r\n"

> body.encoding
 => #<Encoding:Windows-31J>

※EncodingのSJISとWindows_31Jは同じもの
class Encoding (Ruby 3.1 リファレンスマニュアル)

UTF-8に変換 →OK(文字化け解消)

> body.encode(Encoding::UTF_8, invalid: :replace, undef: :replace, universal_newline: true)
 => "テスト\r\n"

文字コードが分からない場合

文字コードがShift_JISだと解っている場合は、force_encodingでエンコーディング情報をSJIS(Windows-31J)に直してからencodeすればOK
文字コードが分からない場合は、NKF.guessで推測すればOK

> require 'nkf'
 => true
> encoding = NKF.guess(body)
 => #<Encoding:Shift_JIS>

> body.force_encoding(encoding)
 => "\x{8365}\x{8358}\x{8367}\r\n"
 
> body.encode(Encoding::UTF_8, invalid: :replace, undef: :replace, universal_newline: true)
 => "テスト\n" 

Faradayの場合

Gemfile

gem 'faraday'
% bundle install
% rails s
> response = Faraday.get('http://localhost:3000/')
 => #<Faraday::Response:0x000000012d9bd380 @on_complete_callbacks=[], @env=#<Faraday::Env @method=:get @url=#<URI::HTTP http://localhost:3000/> @request=#... 
> response.body.encoding
 => #<Encoding:UTF-8> 

ヘッダの「Content-Type: text/html; charset=utf-8」とかを見てそう!

public/にShift_JISのファイルを用意して

> response = Faraday.get('http://localhost:3000/test_sjis.txt')
 => #<Faraday::Response:0x000000012f725850 @on_complete_callbacks=[], @env=#<Faraday::Env @method=:get @url=#<URI::HTTP http://localhost:3000/test_sjis.tx... 
> response.body.encoding
 => #<Encoding:ASCII-8BIT>

Content-Typeがないと、ASCII-8BITを返すので、同様にNKF.guessで推測して、force_encodingでエンコーディング情報を直してからencodeする必要がある。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です