
今、客先のデータをJavaで処理しようとしているのですが、そのデータ(Shift-JISの文字列データ)には、今まで使われてきた「外字」が含まれています。
私の知っている範囲では、Shift-JISの文字列でも、Javaで読み込んだら内部的にUnicodeに変換されるのではないかと思っているのですが(←間違っているかもしれません)、そのUnicode変換の際に外字の部分はどうなってしまうのでしょうか。また、Unicodeに変換された文字列を、出力の際にまたShift-JISに戻すことになると思うのですが、そのときにはちゃんと以前の外字コードに戻ってくれることが保証されているのでしょうか。
JavaのリファレンスでStringクラスのページで「外字」という文字列で検索してみたのですが、まったくひっかからなかったので不安になっています。
よろしくお願い致します。
No.2ベストアンサー
- 回答日時:
#1です。
似たような質問があがっているところを見つけました。
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.ph …
ということで、これを参考に実験です。
UTF-16の外字の領域を一文字ずつShift-JISに変換して、また、UTF-16に戻して、ちゃんともとにもどるか、やってみました。
public class Gaiji {
public static void main(String[] args) throws Exception {
final String charSet = "Shift-JIS";
boolean allEqual = true;
for (char c = 0xE000; c <= 0xF8FF; c++) {
System.out.print(Integer.toHexString((int)c) + "→");
char[] carray = {c};
String source = new String(carray);
byte[] sjis = source.getBytes(charSet);
for (byte b : sjis)
System.out.print(Integer.toHexString(((int)b & 0xFF)));
System.out.print("→");
String result = new String(sjis, charSet);
System.out.print(Integer.toHexString((int)result.charAt(0)) + " : ");
boolean equal = source.equals(result);
System.out.println(equal);
allEqual = (allEqual && equal);
}
System.out.println();
System.out.println("すべて一致 : " + Boolean.toString(allEqual));
}
}
(コンパイルするときは全角スペースを半角スペースに変換してからにしてください)
ところがぜんぜんダメ。
元に戻りません。
ということで、Windowsの本来の文字コードWindows-31Jでやってみました。
final String charSet = "Windows-31J"; ←変更
どうやらうまく行っているのですが、途中までは順調に変換され、元に戻るものの、途中からだめになりました。
どうやら、UTF-16 : E757 Shift-JIS : F9FC の次からだめになっています。
外字エディタで見てみるとちょうどF9FCまでが、Shift-JISの外字領域のようです。
つまり、UTF-16のほうがShift-JISより、外字領域が大きいみたいです。
当然そこから先は、Shift-JISには、変換不能ということになります。
というわけで、
1.Windowsでは、通常ならCharSetがShift-JISでも大体大丈夫だけど、外字の変換をするときにはちゃんとWindows-31Jを指定しないとダメ。
2.UTF-16 : E000~E757 Shift-JIS : F040~F9FC の範囲なら変換可能。
UTF-16 : E758~F8FF の範囲はShift-JISに相手がいないので無理。
ってことで、Shift-JISで外字が設定されているのなら、大丈夫ってことになるんじゃないでしょうか。
参考URL:http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.ph …
No.1
- 回答日時:
こんばんは、興味があったので実験してみました。
(環境 WindowsXP SP2 : JDK 1.5.0_04)
外字エディタにて シフトJISで F040 Unicodeで E000 に外字を作成。(手書きのふにゃふにゃ温泉マーク)
char[] c = {0xE000};
String s = new String(c);
System.out.println(s);
これで、ちゃんと外字が出てきました。
次に、メモ帳にて外字の温泉マークが書いてあるテキストをシフトJISで保存。
BufferedReader br = new BufferedReader(new FileReader("gaiji.txt"));
for (String line; (line = br.readLine()) != null;) {
System.out.println(line);
}
やっぱり、普通に温泉マークが出てきました。
今度は、外字エディタで作った温泉マークを削除。
さっきのコードを実行すると、温泉マークが出てこず、空白になります。
早い話が、char型変数やStringクラスが扱っているのは文字コードという純然たる数字であって、実際にフォントとして描くのはシステムに依存しているって事なんじゃないでしょうか。
つまり、結局のところ、OSでその文字コードに外字が割り当ててあれば、ちゃんと表示され、されていなければ、それなりになるって事だと思います。
この回答への補足
ありがとうございます。
これは
・Shift-JISでは外字領域はF040以降(←これは知ってました)
・UnicodeではE000以降
・それらは1対1で対応している
・たとえばF040<->E000、F041<->E001、というように
・これをやってくれるのは、Javaの仕様
っていうことなんでしょうか。
Unicodeに直した後は、画面には表示する予定はないので、フォントの割り当てなどは気にならないのですが、Shift-JIS変換の際に相互の可逆性があるかどうかが気になっているのです。
ご存じでしたら教えてください。お願いします。<(_ _)>
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
ダブルクォーテーションのrepla...
-
あるディレクトリにある複数の...
-
javaの初歩的な質問です。
-
C言語32bitから64bitの移行につ...
-
文字列の比較
-
javaで質問です。 文字列2023/2...
-
カタカナをローマジに変換する。
-
エクセルVBAで「〜」が表現でき...
-
IF関数でEmpty値を設定する方法。
-
乱数とは・・・?
-
フォームのピクチャーボックス...
-
メインが含まれていません
-
C言語 重複しない4ケタの乱数...
-
JSPやサーブレットでSystem.out...
-
どうしてもプログラムが動いて...
-
指定した座標の色を得るためには
-
プログラミングの問題です。大...
-
javaでのプログラム(配列)につ...
-
Graphics gra = this.getGraphi...
-
テキストボックスに入力された...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
javaで質問です。 文字列2023/2...
-
ダブルクォーテーションのrepla...
-
javascriptで文字列のsjis利用...
-
javaの初歩的な質問です。
-
Visual Basic でのコードをASCI...
-
JavaのStringクラスに「外字」...
-
Path型をString型へ変換する(Java)
-
エクセルVBAで「〜」が表現でき...
-
int型のゼロ埋め
-
JAVAでのShift-JISとEUC-JP間の...
-
C言語32bitから64bitの移行につ...
-
UTF-8とUnicodeの互換性
-
文字列の比較
-
COBOLで半角カナを全角カナに変換
-
substring バイト単位でやりたい
-
Windows-31Jからutf-8への変換...
-
カタカナをローマジに変換する。
-
[Javascript]エンターキー押下...
-
byte型のマイナスの扱いについて
-
文字化け対策について
おすすめ情報