macのrubyで文字コードcp932でファイルに保存されているか確認する際の落とし穴
まずは元々の挙動を確認
まずは何も指定もせずにファイルに保存するとどうなるのか確認してみます。
say_nice.rb
File.open("nice.txt", "w") do |f| f.puts "nice" end
ファイルの文字コードを確認する方法は
$ nkf --guess filename
または$ file --mime filename
なので、
$ nkf --guess nice.txt
で確認すると、
ASCII (LF)
どうやらASCII (LF)
という文字コードで保存されているらしい。
$ file --mime nice.txt
こちらでも確認してみます。
good.txt: text/plain; charset=us-ascii
ふむ。やはりASCIIみたいですね。
それでは、文字コードをcp932に変更します。 ちなみにcp932というのはShift-JISみたいなやつです。若干違うけどほぼ一緒みたいな認識を勝手にしてます。
say_nice.rb
File.open("nice.txt", "w:cp932") do |f| f.puts "nice" end
これで文字コードはcp932になっているはずですね、確認してみましょう。
$ nkf --guess nice.txt
ASCII (LF)
ファッ!? 変わってないやんけ!
念のためこちらでも確認。
$ file --mime nice.txt
good.txt: text/plain; charset=us-ascii
おっかしいなー。
思い通りの文字コードで保存されない理由
思い通りの文字コードで保存されない理由は、アルファベットしかないから。です。
上記のコードたちだとアルファベットしか出力してないから、文字コードを判断するに足る情報が少なかったからです。
文字コードというのはhtmlファイルのhead情報みたいにファイルのどこかに保存されているのかなと、勝手に思ってましたが、ファイルの中身を見て判断しているみたいですね。
テキストファイルの文字コードは中身で決まる。らしい。 - Qiita
こちら参考にさせていただきました。
つまり、nice
だけだと、asciiもutf-8もcp932も同じ文字コードで表現できてしまう。ってこと!か
というわけで、再度確認してみる
再度元々の挙動を確認
日本語文字に変更して、
say_nice.rb
File.open("nice.txt", "w") do |f| f.puts "いいね" end
$ nkf --guess nice.txt
UTF-8 (LF)
$ file --mime nice.txt
good.txt: text/plain; charset=utf-8
日本語文字を含めると、UTF-8で保存されているみたいですね。
いよいよ本題、cp932で保存したい。
File.open("nice.txt", "w:cp932") do |f| f.puts "いいね" end
確認してみる。
$ nkf --guess nice.txt
Shift_JIS (LF)
えぇ〜・・・
こちらも
$ file --mime nice.txt
good.txt: text/plain; charset=unknown-8bit
こっちに至ってはunknown言われてるやん。。。
cp932じゃなく、Shift_JISと解釈される問題
$ file --mime nice.txt
の方はさておき、Shift_JIS (LF)
と判別されるのは、同じく、cp932
とShift_JIS (LF)
を判別する文字がなかったためでした。
cp932にあって、Shift_JISにないものを文字に入れて検証。
①
を追加。
File.open("nice.txt", "w:cp932") do |f| f.puts "いいね①" end
これで
$ nkf --guess nice.txt
CP932 (LF)
よっしゃ!
こちらは?
$ file --mime nice.txt
good.txt: text/plain; charset=unknown-8bit
unknownのまま。
もうfile --mime
のことなんか知らないっ
あとで調べてみるか・・・
cp932で保存はできてるんだもんな。