プロが教える店舗&オフィスのセキュリティ対策術

お世話になっております。

現在javaにて大容量のテキストファイル(100M以上)を読み込んで、
特定の文字が含まれている行のみを別ファイルへ抽出するという
プログラムを作成しています。

現在のロジックでは、

File file = new File( "読み込みファイル" );
byte[] b = new byte[ (int) file.length() ];

FileInputStream fis = new FileInputStream(file);
fis.read(b);

String str = new String(b, "Shift-JIS");

return str;

上記の様なのようなロジックのメソッドを作成し、
返り値の文字列を改行コードでsplitし、パターンマッチングして行を抽出する方法をとっています。

しかしこの方法だと、OutOfMemoryErrorが発生していまい、
30MB以上のファイルを読み込むことができません。
原因がJVMのメモリ領域の問題なのは理解していますが、
readLineをでためしてみると処理終了があまりにも遅すぎるため、
なるべく現在の手法を改良する方向で作成したいのですが、

一回目 :0 ~ 30000000byte まで
二回目 :30000001 ~ 60000000byte まで

の様にJVMの設定はいじらない方法でファイルのデータを、
指定バイトから指定バイトまで読み込む方法等なないでしょうか?
それ以外でも処理が早く、
大容量のテキストファイルを読み込む方法がありましたら、
そちらでも問題ありません。

ぜひとも知恵をお貸しください。
宜しくお願いします。

A 回答 (2件)

readLine()を試したということですが、どのクラスのreadLine()を使ったのでしょう? BufferedReaderでも遅かったのでしょうか?



FileInputStreamで頑張る場合でもそのまま使うのではなくてBufferedInputStreamをかぶせましょう。
(a) 1行の長さより十分長い(たとえば8KB)byteの配列を用意する
(b) そのbyte配列にBufferedInputStreamから8KB分のデータを読み込む
(c) byte配列の中を自力で行を区切って処理する (split()は使えません)
(d) byte配列の最後に1行に満たないデータがnバイト分残った場合は、そのnバイトをbyte配列の先頭へコピーする
(e) byte配列の(n+1)バイト目以降に、続きのデータを(8K-n)バイト分だけBufferedInputStreamから読み込む (read(byte[], int, int)が使えます)
(f) ファイルの最後を読み込むまで(c)~(e)を繰り返す
    • good
    • 0
この回答へのお礼

ありがとうございます。

BufferedInputStreamは使用していなかったのですが、
解答いただいた方法を自分なりに改変することで、
うまく実行することが出来ました。

ちなみにBufferedReaderのreadLineを使用していたのですが、
splitでループを回した時と処理終了が断然違っていたのは、
自分なりに調べてみることにします。

お礼日時:2012/03/07 09:35

マニュアルを読みましょう



http://java.sun.com/javase/ja/6/docs/ja/api/java …[])
『最大 b.length バイトまでのデータを』、この入力ストリームからバイト配列に読み込みます

http://java.sun.com/javase/ja/6/docs/ja/api/java …[],%20int,%20int)
『最大 len バイトまでのデータを』、この入力ストリームからバイト配列に読み込みます。

ただし。
複数バイト文字の途中まで/途中から読む可能性があります。



すなおにreadLine使うのがいいと思うのですが。
100Mのデータはそもそも読めてないわけですから、「readが早い」というのも100M全部では比較できてないんですよね?

あとは、exec("grep '検索文字列' ファイル > 出力ファイル"); とか
    • good
    • 1
この回答へのお礼

書き方が悪かったようで、すいません。

実際にファイル自体は読み込めているのですが、
String str = new String(b, "Shift-JIS");
の時点でoutOfMemoryが発生するという意味でした。

基本はやはりreadLineを使用するのですね。
なぜsplitとreadLineの終了時間に大きく差異が発生したのか、
自分なりに調べて見ることにします。

お礼日時:2012/03/07 09:42

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています