• ベストアンサー

カタカナの「ソ」以降の文字が文字化けします

propertiesファイルから文字列を読み込む処理を行っているのですが、文字列にカタカナの「ソ」がはいると、「ソ」自体とそれ以降の1文字が文字化けしてしまいます。 これには何か対処方法があるのでしょうか? こんな感じの処理を行っています。 【propertiesファイルの内容】 path=C:\\MyWork\\ソース\\download 【読み込み処理】 FileInputStream fis = new FileInputStream(propfile); Properties prop = new Properties(); prop.load(fis); String sjs_path = getString(prop.getProperty("path"); String uni_path = new String(sjs_path.getBytes("iso-8859-1"), "Shift_JIS"); アドバイスよろしくお願いいたします。

質問者が選んだベストアンサー

  • ベストアンサー
  • chie65536
  • ベストアンサー率41% (2512/6032)
回答No.2

「ソ」はシフトJISコードで「835c」ですが、第2バイトの「5c」はエスケープ文字の「\」と同じコードです。 従って「ソ」の次の文字「ー」の第1バイトをエスケープします。つまり「ソ」の第2バイトの「\」が欠落します。 ソース ↓ 83 5c 81 5b 83 58 ↓ 83 \ 81 [ 83 X ←「\ 81」が「81」にエスケープされる ↓ 83 81 [ 83 X ↓ メ[ス これは「ソ」以外にも「Ы」「(9)」「噂」「浬」などの、第2バイトが「\」になる文字で発生します。 読み込むデータをEUCで記述しておくか、中間ファイルにEUCで書き出してから読み込むか、読み込むデータを「C:\\MyWork\\ソ\ース\\download」と書いておくなど、シフトJISコードの第2バイトが「\」になっても構わない書き方をする工夫が必要です。

echo2002
質問者

お礼

とてもわかりやすい説明で、私にもよくわかりました。ありがとうございます。 対応方法もいくつか教えていただけたので、検討してみます。 ありがとうございました。

すると、全ての回答が全文表示されます。

その他の回答 (6)

  • ngsvx
  • ベストアンサー率49% (157/315)
回答No.7

#4です。 なるほど、プロパティーファイルを、シフトJISで書いたんですね。 プロパティーファイルは、Unicode escapesが使用できるようになっていて、 ¥マークを特別扱いします。 そのため、¥マークのある文字は正確なバイト配列になりません。 例えば、ファイルに「ソラ」とあったとします。 (シフトJISで 83h 5ch 83h 89h) これを読んだときに、¥マーク(5ch)があるため、文字列は 83h 83h 89h になってしまいます。 つまり、質問者さんのコードの String sjs_path = getString(prop.getProperty("path"); の部分のsjs_pathは¥マークを除去されたものになっています。 従って、正しい変換はできません。 解決策は、 1.Properties#storeで書き込む。 2.手書きするなら、\uXXXXの形式で(Unicodeで記述する) 3.native2ascii ツールを使用する。 のどれかだと思います。

参考URL:
http://java.sun.com/j2se/1.4/ja/docs/ja/api/java/util/Properties.html
echo2002
質問者

お礼

プロパティファイルはお客様が用意されるので、そちらの都合でSJISコードになってしまうんです・・・。 いくつかご提案いただいた対応策を検討中です。 度々のご回答、ありがとうございました。

すると、全ての回答が全文表示されます。
  • nuki
  • ベストアンサー率30% (6/20)
回答No.6

理由は、ANo.5でお答えになった方の通りです。 対処方法としては、 1.propertiesファイルを予め変換しておく j2seのsdkに含まれるnative2ascii.exeで予め変換して おくと、正常に読み込むことが出来ます。 sdkのインストールフォルダのbinフォルダ下にあります。 こうすればエンコーディングの変換は事前に済ませる ことができます。 2.Jakarta CommonsのExtendedPropertiesを使う java.util.Propertiesを機能拡張した org.apache.commons.collections.ExtendedProperties を使うと、loadの引数にエンコーディング文字列が 使えますので、エンコーディングの変換ソースの 作成がそもそも不要になります。 Jakarta Commonsはオープンソースです。 参考URLに一部の日本語訳サイトを掲示しました。 残念ながら、ExtendedPropertiesは未翻訳の様ですが。

参考URL:
http://www.jajakarta.org/
echo2002
質問者

お礼

対処方法のご提示、ありがとうございます。 どの方法が一番私が作成する機能にうまく組み込めそうか検討中です。 いろいろな方法を教えていただけて助かりました。

すると、全ての回答が全文表示されます。
  • ranx
  • ベストアンサー率24% (357/1463)
回答No.5

java.util.Properties#load() は、ファイルがISO8859-1エンコーディングで書かれていることを 前提としていますから、多バイト文字を含むファイルを読む時には使えません。 Propertiesを拡張したクラスを作ってload()をオーバーライドし、 java.io.InputStreamReader 等でエンコーディングを指定して読み込めばよいと思います。 ひょっとすると、もっとスマートなやり方もあるかもしれませんが。

echo2002
質問者

お礼

> java.util.Properties#load() は、ファイルがISO8859-1エンコーディングで書かれていることを > 前提としていますから、多バイト文字を含むファイルを読む時には使えません。 このことは初めて知りました・・・。 対応方法は他の方々のご提案も含めいろいろ検討してみます。 ありがとうございました。

すると、全ての回答が全文表示されます。
  • ngsvx
  • ベストアンサー率49% (157/315)
回答No.4

>String uni_path = new String(sjs_path.getBytes("iso-8859-1"), "Shift_JIS"); おかしくありませんか? これだと、 「sjs_pathの内容をiso-8859-1のバイト配列にし、 それを(iso-8859-1のバイト配列)をシフトJISとみなして復号化する」 ことになります。

echo2002
質問者

補足

以下のコードの説明ですが、 >String uni_path = new String(sjs_path.getBytes("iso-8859-1"), "Shift_JIS"); ”sjs_pathをiso-8859_1の文字列としてバイト列に変換して、文字コードをShift_JISと仮定してunicodeへ変換する”という意味だと思うんですが・・・。 http://hp.vector.co.jp/authors/VA017148/java/encoding.html を参考にしました。

すると、全ての回答が全文表示されます。
  • chie65536
  • ベストアンサー率41% (2512/6032)
回答No.3

#2です。 >これは「ソ」以外にも「Ы」「(9)」「噂」「浬」などの 「(9)」はローマ数字「IX」です。 教えてgooが勝手に「IX」を「(9)」に書き替えてくれやがりました(怒)

すると、全ての回答が全文表示されます。
noname#256877
noname#256877
回答No.1

文字「ソ」は、SJISで0x835Cとなり、下位1バイトが5Cすなわち「¥(半角文字)」となります。 Javaはあまり詳しくないので、どうしたらいいかまでアドバイスはできませんが、このへんではないでしょうか?

すると、全ての回答が全文表示されます。

関連するQ&A