• ベストアンサー

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

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"); アドバイスよろしくお願いいたします。

  • Java
  • 回答数7
  • ありがとう数5

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

  • ベストアンサー
  • 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

  • Javaのプロパティファイルの文字化け対策

    いつもお世話になっております。 一連の質問で大分クリアになって来たのですが、まだ課題が残っています。 xxx.propertiesファイルを作成したとします。 プロパティに日本語を設定しました。 Java上でgetProperties()をすると文字化けしてしまいます。 初歩的な質問で申し訳ありませんが、具体的な対策をご教示願います。 public String getMailSubject() throws MailSendErrorException { String subject = null; try { Properties prop = new Properties(); // プロパティファイルからキーと値のリストを読み込む prop.load(new FileInputStream(this.properties)); subject = prop.getProperty("mail.subject"); } catch (Exception e) { e.printStackTrace(); throw new MailSendErrorException(); } return subject; } 上記のソースでmail.subjectに設定してある日本語文字列を取得したいのですが色々試しましたが上手く行きません。

    • ベストアンサー
    • Java
  • ファイルよりの文字列の取り込み(Properties)

    下記のプログラムでテキストファイルに"0x5C"を含む文字列を 取り込んだ時に文字化けしてしまいます。 テキストファイルに\\を付加する逃げ方は検索して発見しましたが \\を付加を付加せずに解決する方法は有りませんでしょうか? import java.io.FileInputStream; import java.util.Properties; public class Class1 {  public static void main (String[] args) {   try {    FileInputStream oFileInputStream = new FileInputStream("c:\\test.txt");    Properties oProperties = new Properties();    oProperties.load(oFileInputStream);    String sTmp1 = oProperties.getProperty("100001T");    String sBuf1 = new String(sTmp1.getBytes("8859_1"), "MS932");    String sBuf2 = new String(oProperties.getProperty("100001M").getBytes("8859_1"), "MS932");    System.out.println(sBuf1);    System.out.println(sBuf2);   } catch (Exception oException) {    oException.printStackTrace();   }  } } /* 実行結果 可狽ナす。可狽ナす。可狽ナす。可狽ナす。 可能です。 */ /* test.txtの内容 100001T=可能です。可能です。可能です。可能です。 100001M=可能\\です。 100001S=1 100001L=0 */

    • ベストアンサー
    • Java
  • ファイルパスが取得出来ない(Properties.getProperty使用)

    PropertiesクラスのgetPropertyメソッドを利用して 外部ファイルより値を取得しようとしています。 // ファイルパスの取得 java.util.Properties pr = new Properties(); pr.load(new FileInputStream("sample.properties")); String filePath = pr.getProperty("filePath"); fis.close(); // sample.properties filePath = C:\test\test.txt しかし、エスケープ記号?が問題で下記のようになり うまく取得出来ません。 filePath = C: est est.txt なぜこのような現象が起こるのでしょうか。 また、回避策はありますでしょうか。 よろしくお願いします。

  • Tomcatプロジェクトの.propertiesファイルの置き場

    当方、Tomcat5.0,Eclipseでサーブレットを開発しております。 初歩的な質問で申し訳ありませんが、プロパティファイルの置き場所が 分からず難儀しております。 どなたかご教示願います。 prop.load(new FileInputStream("C:/work/workspace/worktools/mail.properties")); 上記の様にフルパスを指定すると認識するのですが、 prop.load(new FileInputStream("mail.properties")); この様にパスを省略するとFileNotFoundExceptionが発生してしまいます。WEB-INF直下にファイルを置いてるのですが、間違いなのでしょうか?

    • ベストアンサー
    • Java
  • EUC-JP-LINUXの文字化け

    文字化けで困っているのですが,通常有名なエンコードをしても直りませんでした。 それで String enc = System.getProperty("file.encoding"); で表示させたら EUC-JP-LINUX とでましたが、この時の strPar = new String(strPar.getBytes("ISO-8859-1"),"Shift_JIS"); はどうしたらよいのでしょうか? ちなみに画面は contentType = "text/html;charset=Windows-31J" としています。

  • 文字化けします。

    お世話になります。 ソケットでサーバとクライアントを接続しています。 コーディングの概略は次の通りです。 【クライアント】 PrintWriter out = new PrintWriter(socket.getOutputStream(), true); BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream(),"EUC_JP")); out.println("かきくけこ"); System.out.println(in.readLine()); 【サーバ】 PrintWriter out = new PrintWriter(socket.getOutputStream(), true); BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream(),"Shift_JIS")); String inputLine; while ((inputLine = in.readLine()) != null) { System.out.println(inputLine); out.println(inputLine); //←これはクライアントでも文字化けしない。 String s1 = "あいうえお"; String u1 = new String(s1.getBytes("xxxxx"), "yyyyy"); out.println(u1); //←文字化けする。 } お伺いしたいのは文字コード変換についてです。 サーバ:RedhatLinux クライアント:Windowsでして、 サーバ側コーディングの String s1 = "あいうえお"; としている文字列を クライアント側の // 読み込んだデータを表示 System.out.println(in.readLine()); で表示したいのですが、文字が化けて(????←このようになります)困っています。 文字コード変換しなければいけないと思うのですが、 getBytesを使うのでしょうか? もしgetBytesを使うならどのように書けばいいのかがわかりません。 分かりにくい説明で申し訳ありませんが、 ご教授ください。宜しくお願いします。

    • ベストアンサー
    • Java
  • Return で文字列が返せない、、

    このような関数を作って、mainの関数に渡したいのですが、文法がダメだとコンパイラに怒られます。 private String test(){ try{ FileOutputStream fos=openFileOutput("sample.txt", MODE_PRIVATE); String text="サンプルテキストです"; fos.write(text.getBytes()); fos.close(); }catch(FileNotFoundException e){ }catch(IOException e){ } try{ FileInputStream fis=openFileInput("sample.txt"); byte buffer[]=new byte[100]; fis.read(buffer); String str = new String(buffer).trim(); fis.close(); return str; }catch(FileNotFoundException e){ }catch(IOException e){ } }なぜ返せないのでしょうか。

    • ベストアンサー
    • Java
  • プロパティリストをVectorに出力したい場合

    プロパティファイルの中身をVectorに入れたいのですが、 APIを見ると、 list(PrintStream out) 指定された出力ストリームに、プロパティリストを出力します。 と書かれてありますが、PrintStream outの部分をどうやればいいのかかわかりません・・・。 ご教授いただけたら幸いです。 よろしくお願いします。 Properties prop = new Properties(); prop.load(new FileInputStream("./test.properties")); prop.list(???);

    • ベストアンサー
    • Java
  • EUC_JPの文字化け

    指定された文字列(String型)を以下の様にバイト配列で保持し、 byte[] work = "指定文字列".getBytes(encoding); そのバイト配列を使用し、再度、以下の様にStringを生成します。 new String(work, encoding); (作成したプログラムを添付したいのですが、文字数の関係で割愛します。) 指定文字列は機種依存文字(丸数字等)にします。 この時、encodingにMS932、UTF-8等を指定した場合は問題なく元の文字列が 取得できますが、EUC_JPを指定すると、?に文字化けを起こします。 調査すると、getBytesでbyte配列を取得した時点で既に変換不良を起こしていました。 (丸数字全てが0x3fになっていました。期待していたコード、というか本来は、0xADA1~0xADB4のはずです。) そこでStringクラスのgetBytesメソッドをオーバーライドしちゃえという、甘い考えが浮かび、 javaのソースコードでString.javaを見ましたが、結局のところ、どこでコード変換を行っているのか よくわかりませんでした。 そこで質問です。 1)これはJDKのバグなのですか? 2)こんな経験がある。あるいはこういう対処をした。というかた、おりましたら、   参考URLでも構いませんが教えてください。 以上、よろしくお願いします。

  • UNICODEへの文字コード変換

    以下のようにして、 日本語で書かれたファイルを読み込んで、 UNICODEに変換したいのですが、 できません。。。 どこが間違っているのでしょうか?(;;) 元の日本語ファイル「こんにちは」 >>できたファイル「\u3053\u3093\u306b\u3061\u306f」 という風にしたいのですが。。 //FileIOSteramの作成 FileInputStream fis = new FileInputStream(iFile); FileOutputStream fos = new FileOutputStream(oFile); //Stream ラップ InputStreamReader in = new InputStreamReader(fis, "EUC-JP-LINUX"); OutputStreamWriter out = new OutputStreamWriter(fos, "UTF16"); System.out.println(System.getProperty("file.encoding")); //読み込みと書き込み int c; InputStreamReader in = new InputStreamReader(fis, "Unicode"); Writer out = new Writer(fos); while((c = in.read()) != -1){ out.write(c); }

専門家に質問してみよう