1

大きなテキスト ファイル (約 5 メガバイト) を読まなければなりません。

私が使用しているこのファイルを読み取るためにBufferedReader()、メモリリークとヒープの増加が原因です.コードを最適化するための代替オプションはありますか?

            StringBuffer sb = new StringBuffer();
            BufferedReader reader = new BufferedReader(new FileReader(vCache));
            String line = null;

            while ((line = reader.readLine()) != null) 
            {
                sb.append(line);
            }
4

6 に答える 6

1

InputStreamの代わりに使用してみてくださいBufferedReader

try {
    InputStream is = new FileInputStream(vCache);
    byte[] b = new byte[is.available()];
    is.read(b);
    String text = new String(b);
}
于 2013-06-03T11:13:07.797 に答える
1

ローカルファイルを読んでいると思います。この場合、ファイル全体をバイト配列に読み取ってから、文字列に変換する方がよい場合があります。

InputStream is = new FileInputStream(vCache);
byte[] buffer = new byte[is.available()];
is.read(buffer);
is.close();
jsonContent = new String(buffer, "UTF-8");

ただし、Android のこのような大きなファイルをメモリに読み込むことで、問題が発生する可能性があります。5 MB の json ファイルを読み取る必要がある場合、アプリを正しく構成していない可能性があります。

于 2013-06-03T11:13:10.403 に答える
1

bufferSizeによって使用されるデフォルトBufferedRedaer8KBですが、行ごとに読み取っているため、累積はより多くなります。これを改善するには、次を使用できます。

BufferedReader(Reader in, int sz)<--szより小さい値で使用4KB

read(char[] cbuf)<--cbufリーダー サイズの制約サイズ

close()<-- リーダー インスタンスが保持していたメモリはすべて GC できるようになりました

StringBuffer sb必要なメモリ (~fileSize) が利用できない場合に上記の変更を行った後でも、コードは完全なファイル コンテンツのようにすべての行を保持するようにJVMなり、再び OOM の問題が発生します。それがあなたに当てはまるかどうかはわかりませんが、そうでない場合は、上記でローカルメモリのスパイクが少し改善されるはずです。

于 2013-06-03T11:27:12.797 に答える
0

JSONを解析しています。

整形 (インデント、改行など) がある場合は削除することで、入力ファイルを小さくすることができます。

ストリームから直接読み取るパーサーを試すこともできます。一度にすべてをバッファリングする必要がないことを願っています。たとえば、Android はJsonReaderを提供します。これにより、ストリームを解析してデータ構造を自分で制御できます。つまり、よりメモリ効率の高い構造を使用でき、ストリーム全体をバッファリングすることもありません。残念ながら、API レベル 11 で追加されたため、下位互換性が問題になる可能性があります。

1 つの代替方法は、最上位オブジェクトが配列の場合、それをいくつかの小さな配列に分割し、おそらく異なるファイルに分割し、それらを個別に解析してサブ配列をマージすることです。ベース オブジェクトの構造が類似している場合は、それらをマージする前に Java オブジェクトに変換できます。これにより、メモリ構造がよりコンパクトになります。

于 2013-06-03T11:13:00.030 に答える
0

各行が 1 つの完全な db 行と整形式の json に対応するように JSON を送信します。この方法では、ファイル全体を一緒に処理する必要はありません。

//StringBuffer sb = new StringBuffer();
BufferedReader reader = new BufferedReader(new FileReader(vCache));
String line = null;

while ((line = reader.readLine()) != null)  {
  //Parse JSON
  //Insert into local SQLite DB.
}
于 2013-06-03T11:58:27.357 に答える