0

カンマ区切りのテキストファイルを読み取り、データに対していくつかの計算を実行し、更新されたデータを新しいファイルに書き込むJavaアプリケーションを作成しています。入力ファイルには約5億行が含まれているため、実行時にメモリ不足の例外が発生しないように、可能な限り以下をスケーリングしようとしています。以下を改善する方法について何かアイデアはありますか?

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;


public class CsvTest {

  public void readFile() {

    BufferedReader br = null;
    BufferedWriter out = null;

    try {

      br = new BufferedReader(new FileReader("C:\\input.txt"));
      FileWriter fstream = new FileWriter("C:\\output.txt");
      out = new BufferedWriter(fstream);

      String line = null;

      while ((line = br.readLine()) != null) {
        out.write(line + "\r\n");
      }
    }
    catch (FileNotFoundException ex) {
        System.err.println("Error: " + ex.getMessage());
    }
    catch (IOException ex) {
        System.err.println("Error: " + ex.getMessage());
    }
    finally {
      try {
        if (br != null) {
            br.close();
        }
        if(out != null){
            out.close();
        }
      }
      catch (IOException ex) {
          System.err.println("Error: " + ex.getMessage());
      }
    }
  }

  public static void main(String[] args) {
    CsvTest test = new CsvTest();
    test.readFile();
  }
}
4

3 に答える 3

1

java.nio.channels.FileChannelの使用を検討する必要があります。たとえば、このように、標準のjava.ioとjava.nioの比較もあります。NIOは、大規模なI/O操作を行うための方法のようです。

于 2012-11-30T22:06:35.617 に答える
1

あなたのコードはかなり良いです、つまり、メモリに1行だけを保持している入力から出力にデータをストリーミングしているので、メモリ要件の観点からは基本的にO(1)であり、私が思うよりも良くなることはできません。

バッファリングされたリーダーとバッファリングされたライターのバッファは一定であり、マルチGBファイルのサイズ、メモリ使用量に比べてごくわずかです。

編集:そしてガベージコレクターは未使用のデータを収集するのにうまくいくはずです、少なくともデータ処理の同様のケースでの私の経験はかなりポジティブでした。

于 2012-11-30T22:15:25.430 に答える
1
    out.write(line + "\r\n");

として行くことができます

    out.write(line);
    out.write("\r\n");

文字列のように同じオブジェクト値を持つセルを処理する場合は、複数のオブジェクトインスタンスと同じ値を保持しないことをお勧めします。

private Map<Object, Object> sharedMap = new HashMap<Object, Object>();

public Object uniqueObject(Object value) {
    Object sharedValue = sharedMap.get(value);
    if (sharedValue == null) {
        sharedValue = value;
        sharedMap.put(sharedValue, sharedValue);
    }
    return sharedValue;
}
于 2012-11-30T22:29:05.480 に答える