人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

RubyでUTF-8でのファイル入出力について質問です。
UTF-8のテキストファイルを読み込み、putやp等で出力すると、必ず最初の文字の先頭に
存在しない「・」が勝手に挿入されてしまいます。
「・」が挿入されない様にするにはどうすれば良いか教えて頂けますでしょうか。

利用環境は以下になります。
OS:Windows7 pro SP1
IDE:NetBeans7.0.1
Rubyバージョン:ruby 1.9.3p194

テキスト内容は以下になります。(UTF-8で保存)
10
20
30
田中
佐藤

出力結果が以下の様になります。
????????・10
20
30
田中
佐藤

以上の出力結果の10の前に「・」が勝手に挿入されている状態となります。
ちなみにエンコードを別のに変えて保存した場合は「・」は無くなります。

参考になるか分かりませんが、IDEで表示されている「・」をコピーして
テキストエディタに貼り付けると「?」で表示され、Windows標準のメモ帳に貼り付け
ようとすると、貼り付けが出来ない状態(存在しない状態)となります。
また、external_encodingはUTF-8になっている事を確認しています。

以上の原因と対策を教えて頂けますでしょうか。
何卒宜しくお願い致します

●質問者: suica123
●カテゴリ:コンピュータ インターネット
○ 状態 :終了
└ 回答数 : 3/3件

▽最新の回答へ

1 ● パパトモ
●24ポイント

ファイル冒頭に保存されているデータは、BOM(Byte Order Mark)ではないでしょうか。BOMが付いているなら、Unicodeファイルの仕様通りと言えると思います。

http://e-words.jp/w/BOM.html

バイナリエディタ等でコードをみるとはっきりすると思います。


パパトモさんのコメント
もしBOMであるなら、何故BOMが問題になるのか気になります。

suica123さんのコメント
BOM(Byte Order Mark)の存在を初めて知りました。 教えて頂きありがとう御座います。 無事、解決できました。

2 ● うぃんど
●50ポイント ベストアンサー

BOM有りのUTF-8ファイルを読み込んでいるものと思われます。
(ファイルの先頭にバイトオーダーの情報があるファイル)

元のデータを作成する側でBOM無し保存できるなら、
それに越したことはありません。

データ作成側での対応が無理で、ruby側で対処するならば、
BOM付きであることを明示してopenすると良いでしょう。

open(ファイル名, 'r:BOM|UTF-8')

BOMの有無が判らない場合は、
先頭の3バイトが以下であれば、削れば良いでしょう。
http://ja.wikipedia.org/wiki/%E3%83%90%E3%82%A4%E3%83%88%E3%82%AA%E3%83%BC%E3%83%80%E3%83%BC%E3%83%9E%E3%83%BC%E3%82%AF

0xEF 0xBB 0xBF

suica123さんのコメント
BOMの存在を初めて知りました。 分かりやすい回答ありがとう御座います。 おかげ様で、エンコードを変更したら解決できました。 大変助かりました。

3 ● a-kuma3
●50ポイント

BOM(Byte Order Mark)ですね。

http://ruby.11.n6.nabble.com/ruby-dev-32979-BOM-of-UTF-td3519737.html

まつもと ゆきひろです
...
|つぎに現状でdon't care であるとして、それは仕様として(とりあえずの
|形であっても)固定されたものですか?

将来にわたって対応しないと断言するほどではないですが、対応す
る予定はありません。

と、昔の情報では、こんなことを書いています。
なので、こんな対応をしているのも見つかります。

http://stackoverflow.com/questions/5011504/is-there-a-way-to-remove-the-bom-from-a-utf-8-encoded-file

 content.gsub!("\xEF\xBB\xBF".force_encoding("UTF-8"), '')

でも、最新のバージョンでは、対応されてるみたい。

http://doc.ruby-lang.org/ja/1.9.3/method/Kernel/m/open.html

エンコーディングの指定
ext_enc(外部エンコーディング)が指定されている場合、読み込まれた文字列にはこのエンコーディングが指定され、出力する文字列はそのエンコーディングに変換されます。
ext_encが'-bom'で終わる場合、その入力に含まれるBOMはあらかじめ削られます。また、BOMがあった場合、入力された文字列にはそのBOMに対応するエンコーディングが設定されます。

でも、ちょっと罠があるらしく...
http://smileruby.hatenablog.com/entry/20110221/1298298952

つーか、Encodingに-bomで終わるのなんてあたっけ?


で、こうなんだとか。

念のためこっち(Index of Classes & Methods in Ruby 1.9.3 (Ruby 1.9.3) )で確認したら…
『If ext_enc starts with ‘BOM|’,? 』ってなっている!!
ってことでコチラが正解

puts File.open("utf8.txt", "r:UTF-8"){ |fp| fp.read(6).dump }
# => "\xEF\xBB\xBF20\t"
puts File.open("utf8.txt", "r:BOM|UTF-8"){ |fp| fp.read(3).dump }
# => "20\t"
puts File.open("utf8n.txt", "r:BOM|UTF-8"){ |fp| fp.read(3).dump }
# => "20\t"

http://www.ruby-doc.org/core-1.9.3/Kernel.html#method-i-open

If ext_enc starts with ‘BOM|’, check whether the input has a BOM. If there is a BOM, strip it and set external encoding as what the BOM tells.


suica123さんのコメント
BOMの存在を初めて知りました。 詳細な回答ありがとう御座います。 おかげ様で、BOMの対処法が分かりました。 大変助かりました!。
関連質問

●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ