BufferedReader での文字化け

3,971 views
Skip to first unread message

Salt

unread,
Jul 11, 2009, 1:02:17 AM7/11/09
to 日本Androidの会
初めて書き込みさせてもらいます。salt と申します。

一件、質問させて下さい。

UTF-8 日本語テキストファイルを、BufferedReader を使って読み込むと、
なぜか文字化けしてしまいます。
なぜでしょう?アドバイス頂けると幸いです。

テストしたコードは以下の通りです。
何かプロジェクトを作ってもらって、--- ↓ --- と --- ↑ --- の間をコピペしてもらえると試せると思います。
私の環境では、ADP1 も Emu も同じところで4箇所化けます。

何かコード的に間違ってますでしょうか?

よろしくお願いします。


/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

//---------- ↓ ----------

// テキストファイルを作る
String strFullPathName = "/data/data/" + getPackageName() + "/
test.txt";
makeFile(strFullPathName);

// テキストとしてリードライトテストをする
testReadWrite(strFullPathName);

//---------- ↑ ----------
}

//---------- ↓ ----------

public void makeFile(String strFullPathName) {
File fileOut = new File(strFullPathName);
fileOut.getParentFile().mkdirs();

FileOutputStream fos = null;
OutputStreamWriter osw = null;
BufferedWriter bw = null;

try {
fos = new FileOutputStream(fileOut);
osw = new OutputStreamWriter(fos);
bw = new BufferedWriter(osw);

String str = "あいうえおかきくけこ"; //
"abcdefghijklmnopqrstuvwxyz"; なら問題なし
for (int i = 0; i < 2000; ++i) {
bw.write(str);
bw.newLine();
}
}
catch (IOException ioe) {
ioe.printStackTrace();
}
finally {
if (bw != null) {
try {
bw.close();
osw.close();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

public void testReadWrite(String strFullPathName) {
File fileIn = new File(strFullPathName);
FileInputStream fis = null;
InputStreamReader isr = null;
BufferedReader br = null;

File fileOut = new File(strFullPathName + ".tmp");
FileOutputStream fos = null;
OutputStreamWriter osw = null;
BufferedWriter bw = null;

try {
fis = new FileInputStream(fileIn);
isr = new InputStreamReader(fis);
br = new BufferedReader(isr); // buffer size
を何かしら指定すれば問題は減る

fos = new FileOutputStream(fileOut);
osw = new OutputStreamWriter(fos);
bw = new BufferedWriter(osw);

int nLine = 0;
String str;
while ((str = br.readLine()) != null) {
++nLine;
if (str.indexOf('\uFFFD') >= 0) { // エラーだとこれに変換される
Log.e("test", "read error! at line " +
Integer.toString(nLine));
}

bw.write(str);
bw.newLine();
}
}
catch (IOException ioe) {
ioe.printStackTrace();
}
finally {
if (br != null) {
try {
br.close();
isr.close();
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}

if (bw != null) {
try {
bw.close();
osw.close();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

//---------- ↑ ----------

kenmaz

unread,
Jul 11, 2009, 2:57:38 AM7/11/09
to 日本Androidの会
こんにちは。
単純にUTF-8なファイルの読み書きなら、以下のようにエンコーディングを明示するとどうでしょう?

==============================
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;


public class Test {
public static void main(String[] args) {
BufferedReader br = null;
BufferedWriter bw = null;
try {
br = new BufferedReader(new InputStreamReader(new FileInputStream
("utf8file.txt"), "UTF-8"));
bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream
("out.txt"), "UTF-8"));
String line = null;
while((line = br.readLine()) != null){
bw.write(line);
bw.newLine();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if(br != null){
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(bw != null){
try {
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
=======================

大崎正則

unread,
Jul 11, 2009, 4:01:14 AM7/11/09
to android-g...@googlegroups.com
初めて書き込みさせてもらいます、 大崎 と申します。

自分も検証した際にはまっていましたが、
テストデータが少ないためエディタによっては、
自動認識してくれないのではないでしょうか?
自分の使ってるエディタの場合、テストデータを

あいうえおかきくけこさしすせそ

にすると自動認識し始めました。

あとひとつアドバイスを言えば
アプリケーションのパスにファイルを保存する場合は

openFileInput ,  openFileOutput

を利用されるのもいいかもしれません。


2009/07/11 14:02 Salt <sal...@gmail.com>:

山本 正浩

unread,
Jul 11, 2009, 6:32:45 AM7/11/09
to android-g...@googlegroups.com
yamamoto です。


MLは随分前からチェックしていましたが、投稿は初めてです。

私も試してみましたが、確かにAndroid上ででだけエラーになりますね。
同じコードを、Androidのフレームワークに依存する部分だけ書き換えて
Linux上のVMで動作させると特に問題が出ません。


2009/07/11 17:01 に 大崎正則<mos...@gmail.com> さんは書きました:


--
-<Thinkmeta>------------------------------------------
<?xml version="1.0" encoding="ISO-2022-JP" ?>
<signature>
<name>山本 正浩[Masahiro Yamamoto]</name>
<mail>yama...@thinkmeta.jp</mail>
<mail>yama...@netbeans.jp</mail>
<web>http://www.thinkmeta.jp/</web>
<weblog>http://blog.livedoor.jp/thinkmeta/</weblog>
</signature>

Salt

unread,
Jul 11, 2009, 7:00:44 AM7/11/09
to 日本Androidの会
Salt です。レスありがとうございます。

>>大崎さん
micorSD も使いたいのですよね。。。
テストデータは、2000回繰り返してるので、そこそこでかいです。
元々は Web サイトから取ってて、なぜかでかいサイトだと化けるので、
上記のテストプログラムで試してみたのでした。

>>山本さん
テストありがとうございます。
やっぱり化けますよね。
Linux 上の VM とは、JavaVM で、Android じゃないってことですよね?
バグなのですかね??


On 7月11日, 午後7:32, 山本 正浩 <yamam...@thinkmeta.jp> wrote:
> yamamoto です。
>
> MLは随分前からチェックしていましたが、投稿は初めてです。
>
> 私も試してみましたが、確かにAndroid上ででだけエラーになりますね。
> 同じコードを、Androidのフレームワークに依存する部分だけ書き換えて
> Linux上のVMで動作させると特に問題が出ません。
>
> 2009/07/11 17:01 に 大崎正則<mosa...@gmail.com> さんは書きました:
> >> BufferedReaderbr = null;
>
> >> File fileOut = new File(strFullPathName + ".tmp");
> >> FileOutputStream fos = null;
> >> OutputStreamWriter osw = null;
> >> BufferedWriter bw = null;
>
> >> try {
> >> fis = new FileInputStream(fileIn);
> >> isr = new InputStreamReader(fis);
> >> br = newBufferedReader(isr); // buffer size
> <mail>yamam...@thinkmeta.jp</mail>
> <mail>yamam...@netbeans.jp</mail>
> </signature>- 引用テキストを表示しない -
>
> - 引用テキストを表示 -

Salt

unread,
Jul 11, 2009, 6:56:34 AM7/11/09
to 日本Androidの会
Salt です。レスありがとうございます。

"UTF-8" を指定してみましたが、結果は同じでした;;

FileInputStream & InputStreamReader の代わりに FileReader を使っても結果は同じですね。
BufferedReader があやしい。。。

#元々は、Shift_JIS な Web サイトから取得したデータを一旦そのままファイルに落とし、
#それを加工しながらデフォルト Encoding な UTF-8 で保存して、
#それをアプリで扱うようにしてました。
#(Shift_JIS で保存するより少し速かったので。)
#なので、FileReader ではなく、FileInputStream & InputStreamReader を使ってます。



On 7月11日, 午後3:57, kenmaz <kentaro.matsu...@gmail.com> wrote:
> こんにちは。
> 単純にUTF-8なファイルの読み書きなら、以下のようにエンコーディングを明示するとどうでしょう?
>
> ==============================
> import java.io.BufferedReader;
> import java.io.BufferedWriter;
> import java.io.FileInputStream;
> import java.io.FileOutputStream;
> import java.io.IOException;
> import java.io.InputStreamReader;
> import java.io.OutputStreamWriter;
>
> public class Test {
> public static void main(String[] args) {
> BufferedReaderbr = null;
> BufferedWriter bw = null;
> try {
> br = newBufferedReader(new InputStreamReader(new FileInputStream
> > BufferedReaderbr = null;
>
> > File fileOut = new File(strFullPathName + ".tmp");
> > FileOutputStream fos = null;
> > OutputStreamWriter osw = null;
> > BufferedWriter bw = null;
>
> > try {
> > fis = new FileInputStream(fileIn);
> > isr = new InputStreamReader(fis);
> > br = newBufferedReader(isr); // buffer size
> > //---------- ↑ ----------- 引用テキストを表示しない -
>
> - 引用テキストを表示 -

山本 正浩

unread,
Jul 11, 2009, 9:14:33 AM7/11/09
to android-g...@googlegroups.com
yamamotoです。

> テストありがとうございます。
> やっぱり化けますよね。
> Linux 上の VM とは、JavaVM で、Android じゃないってことですよね?
> バグなのですかね??

試したLinux上のVMは、通常のJVMで、もちろんAndroidのVMではありません。

Android と同じく、デフォルトのエンコーディングがUTF-8のOS上で動くJVMで、
純粋にJavaのロジック中でエラーが出るかどうかを見てみました。
(WindowsだとシフトJISになってしまいますので・・・。)

Android SDKが提供するコアライブラリやVMは、Sunなどのものと完全互換では
なかったと思うので動きが違うこと自体はありうると思います。


openFileInput()でも結果は変わらないみたいですね。

<mail>yama...@thinkmeta.jp</mail>
<mail>yama...@netbeans.jp</mail>
<web>http://www.thinkmeta.jp/</web>
<weblog>ttp://blog.livedoor.jp/thinkmeta/</weblog>
</signature>

Salt

unread,
Jul 11, 2009, 2:09:58 PM7/11/09
to 日本Androidの会
Salt です。

なるほど、UTF-8 な JVM で試してもらったってことなのですね。
opneFileInput() でのテストもありがとうございます。

完全互換ではないとしても、化けてもらっちゃこまりますよね。。。
とりあえず、BufferedReader(isr, 1024); とか、適当にバッファサイズを指定すれば化けは減るので、
それで回避しますかね。(でかいデータだと、どこかで化けるけど;;)

US の方に書き込もうかな。英語力無さすぎですが^^;
> <mail>yamam...@thinkmeta.jp</mail>
> <mail>yamam...@netbeans.jp</mail>
> <web>http://www.thinkmeta.jp/</web>
> <weblog>ttp://blog.livedoor.jp/thinkmeta/</weblog>
Reply all
Reply to author
Forward
0 new messages