スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

ZipからStreamを取得して、BufferedReaderで読み込むと文字化けならぬ文字欠け

補足
---------------------------------------------------------

どうやら、FileInputStreamからBufferedReaderとした場合でも

起こることがあるようです。

---------------------------------------------------------

Zip機能を使ってZipからStream取得して、BufferedReaderで読み込むと

一部文字化けしたりしますね。(MS932)

「へ」が「aA」になったりします。

※ファイル名の文字化けとは違います。

Issue
http://code.google.com/p/android/issues/detail?id=4489


概要
該当行に関してはこんな感じ。

※この行のみのテキストを作って、zipに固めて読み込んでも再現はしません。

正)鳩の胸が光にふるへ、

誤)鳩の胸が光にふるaA


取得した行を1文字ずつ Integer#toBinaryString

正)1001110011101001110000011011101000000011111000110000010011001010001010010011100001000101011000001101011110000011101011100001000101111111111010000011000001

誤)100111001110100111000001101110100000001111100011000001001100101000101001001110000100010101100000110101111000001110101110000100010111100000111100011000000000001


取得した行を1文字ずつ Integer#toHexString

正)9ce9306e80f8304c5149308a306b3075308b30783001

誤)9ce9306e80f8304c5149308a306b3075308bff4141



なんとなく、以下のソースでwriteする際に「len」の指定を忘れていたときの動作に似てる気がする。

int len;
while ((len = bis.read(buff)) >= 0) {
bos.write(buff, 0, len);
}

ant版でも同じ
java.utilのZipFileでも、ant版でも同じだなぁ・・・

Android関係なしの単体テストだと問題ないんだが・・・

android特有?


状況が発生したファイル
条件がいまいちよくわからんのだけど・・・

以下のファイルで確認。

http://www.aozora.gr.jp/cards/000190/card1029.html


読み込みはこんな感じ。

ZipFile zipFile = ...;
ZipEntry entry = ...;
InputStream is = zipFile.getInputStream(entry);
BufferedReader br = new BufferedReader(new InputStreamReader(is, "MS932"));
String line = "";
while ((line = br.readLine()) != null) {
//TODO
}

しかも特定の文字がおかしいというわけではなく、

化けるファイルを、サイズ削ってみたりすると化けなかったりする。

当然解凍後なら問題なし。


なんとなく思うこと、と回避策?
また、BufferedReaderのバッファサイズを指定してやったりすると動作が異なる。(小さめにするとうまくいく)

なんとなく、バッファリングがうまくいっていないだけのような気もする。

さて困った。

256位だとうまくいく。

今回の場合、試した結果、境界は432と433の間にありました。

※これまた微妙な数字ですね。他のファイルだとまた違うかも・・・


検証用プロジェクト
検証用のプロジェクトを用意しました。

上記の青空文庫のファイルを、SDルートにおいて実行すると再現できると思います。

http://cid-bedc048f8064b67b.skydrive.live.com/self.aspx/%E5%85%AC%E9%96%8B/zipread.zip


回避策
というわけで、迂回策をとってみた。

一度オンメモリにbyte[]で展開。


ZipFile→InputStream→BufferedInputStream→

ByteArrayOutputStream→byte[]


byte[]→ByteArrayInputStream→InputStreamReader→BufferedReader


これで回避は出来るものの、オンメモリがなぁ・・・

一時領域にファイルを書き出してもいいんだけど・・・


悩ましい。
関連記事

コメントの投稿

非公開コメント

--


どうやら、FileInputStreamからBufferedReaderとした場合でも


起こることがあるようです。



--


テキストをZipからStream取得して、BufferedReaderで読み込むと


一部文字化け(というか、欠け?)したりしますね。(MS932)


「へ」が「aA」になったりします。


※ファイル名の文字化けとは違います。




Issue

Issueをあげました。


http://code.google.com/p/android/issues/detail?id=4489" target="_blank">http://code.google.com/p/android/issues/detail?id=4489




20100724追記

修正されclose(リリース)されたようです。


結局DalvikVM?の問題だった模様。


概要


該当行に関してはこんな感じ。


※この行のみのテキストを作って、zipに固めて読み込んでも再現はしません。


正)鳩の胸が光にふるへ、


誤)鳩の胸が光にふるaA




取得した行を1文字ずつ Integer#toBinaryString


正)1001110011101001110000011011101000000011111000110000010011001010001010010011100001000101011000001101011110000011101011100001000101111111111010000011000001


誤)100111001110100111000001101110100000001111100011000001001100101000101001001110000100010101100000110101111000001110101110000100010111100000111100011000000000001




取得した行を1文字ずつ Integer#toHexString


正)9ce9306e80f8304c5149308a306b3075308b30783001


誤)9ce9306e80f8304c5149308a306b3075308bff4141






なんとなく、以下のソースで「len」の指定を忘れていたときの動作に似てる気がする。



int len;
while ((len = bis.read(buff)) >= 0) {
bos.write(buff, 0, len);
}



ant版でも同じ


java.utilのZipFileでも、ant版でも同じだなぁ・・・


http://android.g.hatena.ne.jp/keyword/Android" class="okeyword">Android関係なしの単体テストだと問題ないんだが・・・


android特有?




状況が発生したファイル


条件がいまいちよくわからんのだけど・・・


以下のファイルで確認。


http://www.aozora.gr.jp/cards/000190/card1029.html" target="_blank">http://www.aozora.gr.jp/cards/000190/card1029.html




読み込みはこんな感じ。



ZipFile zipFile = ...;
ZipEntry entry = ...;
InputStream is = zipFile.getInputStream(entry);
BufferedReader br = new BufferedReader(new InputStreamReader(is, "MS932"));
String line = "";
while ((line = br.readLine()) != null) {
//TODO
}



しかも特定の文字がおかしいというわけではなく、


化けるファイルを、サイズ削ってみたりすると化けなかったりする。


当然解凍後なら問題なし。




なんとなく思うこと、と回避策?


また、BufferedReaderのバッファサイズを指定してやったりすると動作が異なる。(小さめにするとうまくいく)


なんとなく、バッファリングがうまくいっていないだけのような気もする。


さて困った。


256位だとうまくいく。


今回の場合、試した結果、境界は432と433の間にありました。


※これまた微妙な数字ですね。他のファイルだとまた違うかも・・・




検証用プロジェクト


検証用のプロジェクトを用意しました。


上記の青空文庫のファイルを、SDルートにおいて実行すると再現できると思います。


http://cid-bedc048f8064b67b.skydrive.live.com/self.aspx/%E5%85%AC%E9%96%8B/zipread.zip" target="_blank">http://cid-bedc048f8064b67b.skydrive.live.com/self.aspx/%E5%85%AC%E9%96%8B/zipread.zip




回避策


というわけで、迂回策をとってみた。


一度オンメモリにbyte[]で展開。




ZipFile→InputStream→BufferedInputStream→


ByteArrayOutputStream→byte[]




byte[]→ByteArrayInputStream→InputStreamReader→BufferedReader




これで回避は出来るものの、オンメモリがなぁ・・・


一時領域にファイルを書き出してもいいんだけど・・・




悩ましい。




追記


基本的にはzipは実験機能とした。


勝手に展開するくらいなら最初から展開して配置してね。と。


ただ、青空文庫からのダウンロードを搭載した場合、オプションで解凍機能はつけてもよいかもなぁ。


というか、SmartQ5以外の端末がよくわからん。どのくらいのスペックなんだろう。


オンメモリも厳しいのかなぁ?と思うけど、画像表示に比べれば全然ましなはずだけど。



承認待ちコメント

このコメントは管理者の承認待ちです

承認待ちコメント

このコメントは管理者の承認待ちです

承認待ちコメント

このコメントは管理者の承認待ちです
スポンサードリンク
アプリ一覧
最新記事
最新コメント
最新トラックバック
検索フォーム
月別アーカイブ
カテゴリ
RSSリンクの表示
リンク
QRコード
QR
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。