- PR -

FileReader.readの中身について

投稿者投稿内容
hiro-ta
ベテラン
会議室デビュー日: 2003/09/03
投稿数: 79
投稿日時: 2004-11-10 12:38
ところでchar型もUnicodeでもっていると思うのですが
FileReaderをreadして取得したcharの中身をみてみるとおかしな出力になっています。
なぜこのような結果になるのでしょうか?

[CODE]
FileReader fr = new FileReader("test.txt");
char[] cbuf = new char[10];
int len = fr.read(cbuf, 0, 10);
for (int i = 0; i < len; i++)
System.out.println(Integer.toHexString((int)cbuf[i]));
[/CODE]

[test.txtファイルの中身]
あいう[EOF]

[出力結果]
test.txtがShift_JISエンコードの場合
3042 3044 3046   // UTF-16に変換されているので正しい?

test.txtがUTF-8エンコードの場合
7e3a 3085 ff1e 7e3a // ?

test.txtがUTF-16エンコードの場合
fffd fffd 42 30 44 30 46 30 // ???
hiro-ta
ベテラン
会議室デビュー日: 2003/09/03
投稿数: 79
投稿日時: 2004-11-10 12:47
すみません、書きかけで送信してしまいました。

Javaのchar型はUnicodeだったと思いますがFileReaderでファイルの内容をreadして取得した結果というのはかならずしもUnicodeにはならないのでしょうか?
コードを書いてテストしてみましたがおかしな結果になりました。
なぜこのような結果になるかわかる方いらっしゃらないでしょうか?

コード:
FileReader fr = new FileReader("test.txt"); 
char[] cbuf = new char[10]; 
int len = fr.read(cbuf, 0, 10); 
for (int i = 0; i < len; i++) 
System.out.println(Integer.toHexString((int)cbuf[i])); 



[test.txtファイルの中身]
あいう[EOF]

[出力結果]
test.txtがShift_JISエンコードの場合
3042 3044 3046   // UTF-16に変換されているので正しい?

test.txtがUTF-8エンコードの場合
7e3a 3085 ff1e 7e3a // ?

test.txtがUTF-16エンコードの場合
fffd fffd 42 30 44 30 46 30 // ???
uk
ぬし
会議室デビュー日: 2003/05/20
投稿数: 1155
お住まい・勤務地: 東京都
投稿日時: 2004-11-10 13:02
Readerが自動的に文字コードを判別してくれるわけではありません。何も指定しなければ
デフォルトエンコーディング(file.encodingシステムプロパティで取得できます)を使って
読み込まれます。通常WindowsではWindows-31Jがデフォルトエンコーディングですから、
たとえEUCのファイルであってもWindows-31Jとして読み込んでしまいます。
Kissinger
ぬし
会議室デビュー日: 2002/04/30
投稿数: 428
お住まい・勤務地: 愛知県
投稿日時: 2004-11-10 13:08
私の環境、J2SE1.4.2 / Windows 2000では、file.encoding=MS932
になってました。
uk
ぬし
会議室デビュー日: 2003/05/20
投稿数: 1155
お住まい・勤務地: 東京都
投稿日時: 2004-11-10 13:20
MS932とWindows-31Jは同じですよね。
未記入
ぬし
会議室デビュー日: 2004/09/17
投稿数: 667
投稿日時: 2004-11-10 13:56
引用:

test.txtがShift_JISエンコードの場合
test.txtがUTF-8エンコードの場合
test.txtがUTF-16エンコードの場合


SJIS, JIS, EUC だけであれば JISAutoDetect を指定して InputStreamReader を作成することで、ある程度 自動判別できるんですけど、UTF-8/16 も含めて自動判別というのは標準機能だけでは難しいですね。

とりあえず、JISAutoDetect を使った Reader 作成例

コード:

Reader r = new InputStreamReader(new FileInputStream("test.txt"), "JISAutoDetect");


ちなみに、Shift_JIS ≒ Windows-31J = MS932 なので注意。

[ メッセージ編集済み 編集者: 未記入 編集日時 2004-11-10 13:58 ]
hiro-ta
ベテラン
会議室デビュー日: 2003/09/03
投稿数: 79
投稿日時: 2004-11-10 18:30
皆様、お返事ありがとうございます。

引用:

Readerが自動的に文字コードを判別してくれるわけではありません。何も指定しなければデフォルトエンコーディング(file.encodingシステムプロパティで取得できます)を使って
読み込まれます。通常WindowsではWindows-31Jがデフォルトエンコーディングですから、
たとえEUCのファイルであってもWindows-31Jとして読み込んでしまいます。



デフォルトエンコーディングを変更する方法は無いでしょうか?
System.setProperty("file.encoding", ...)は機能しないということが
http://www.gimlay.org/~javafaq/S146.html
に書いてありました。
実際やってみましたがやはりダメでした。
でくのぼう
大ベテラン
会議室デビュー日: 2003/10/06
投稿数: 162
投稿日時: 2004-11-10 18:46
JVM が 1.4.2 以上なら大丈夫なはずです。

参考: http://www.simeji.com/wiki/pukiwiki.php?Java%A4%CE%CD%AB%DD%B5

スキルアップ/キャリアアップ(JOB@IT)