9

これを行うためのよりクリーンで高速な方法はありますか:

BufferedReader inputReader = new BufferedReader(new InputStreamReader(context.openFileInput("data.txt")));
String inputString;
StringBuilder stringBuffer = new StringBuilder();
while ((inputString = inputReader.readLine()) != null) {
    stringBuffer.append(inputString + "\n");
}
text = stringBuffer.toString();
byte[] data = text.getBytes();

基本的に、ファイルを に変換しようとしてbyte[]いますが、ファイルが十分に大きい場合を除いて、メモリ不足エラーが発生します。私は解決策を探していましたがここでこれをやろうとしましたが、うまくいきませんでした。どんな助けでも大歓迎です。

4

7 に答える 7

6

いくつかの提案:

  1. 文字列ビルダーを作成する必要はありません。ファイルからバイトを直接読み取ることができます。
  2. 複数のファイルを読み取る場合は、不要な場合でもメモリに残っている byte[] 配列を確認してください。
  3. 最後に、-Xmx オプションを使用して Java プロセスの最大メモリを増やします。
于 2013-01-30T07:45:11.230 に答える
3

このファイルのサイズがわかっているので、指定されたサイズのバイト配列を展開するのではなく直接割り当てることで、メモリの半分を節約できます。

byte [] data = new byte[ (int) file.length() ];
FileInputStream fin = new FileInputStream(file);
int n = 0;
while ( (n = fin.read(data, n, data.length() - n) ) > 0);

これにより、不要な追加構造の割り当てが回避されます。バイト配列は一度だけ割り当てられ、最初から正しいサイズになります。while ループは、すべてのデータがロードされることを保証します (read(byte[], offset, length)ファイルの一部のみを読み取る場合がありますが、読み取ったバイト数を返します)。

明確化: StringBuilder が不足すると、初期バッファーの 2 倍の大きさの新しいバッファーが割り当てられます。現時点では、最小必要量の約 2 倍のメモリを使用しています。最も劣化したケース (最後の 1 バイトがすでに大きなバッファーに収まらない) では、最小量の RAM のほぼ 3 倍が必要になる場合があります。

于 2013-01-30T07:47:13.127 に答える
2

ファイル全体を保存するのに十分なメモリがない場合は、アルゴリズムを再考して、大きなbyte[]配列データを構築せずに、読み取り中にファイル データを処理することができます。

javaパラメータをいじってメモリを増やし-Xmxようとしたことがある場合は、サイズが大きいためにそこに配置できないデータをメモリに保存できる解決策はありません。

于 2013-01-30T07:43:59.363 に答える
-1

「よりクリーンで迅速な方法」は、まったく実行しないことです。スケーリングしません。ファイルを一度に 1 つずつ処理します。

于 2013-01-30T11:36:16.523 に答える
-2

このソリューションは、ロードする前に空きメモリをテストします...

File test = new File("c:/tmp/example.txt");

    long freeMemory = Runtime.getRuntime().freeMemory();
    if(test.length()<freeMemory) {
        byte[] bytes = new byte[(int) test.length()];
        FileChannel fc = new FileInputStream(test).getChannel();
        MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_ONLY, 0, (int) fc.size());

        while(mbb.hasRemaining()) {
            mbb.get(bytes);
        }
        fc.close();
    }
于 2013-01-30T07:55:28.877 に答える