まず、すべての行がリストに追加されているので、あなたはメモリが不足しています。
2番目は非常に遅いString.split()を使用しています。
この形式(デリミタ、引用符などのエスケープを処理する必要があります)の周りに多くのエッジケースがあるため、独自の解析コードを記述することでCSVを処理しないでください。
解決策は、univocity-parsersのようなライブラリを使用することです。あなたは1秒未満で100万行を読むことができるはずです。パースする
、ちょうどこの操作を行います。
public static IterableResult<String[], ParsingContext> readCSV(String filePath) {
File file = new File(filePath);
//configure the parser here. By default all values are trimmed
CsvParserSettings parserSettings = new CsvParserSettings();
//create the parser
CsvParser parser = new CsvParser(parserSettings);
//create an iterable over rows. This will not load everything into memory.
IterableResult<String[], ParsingContext> rows = parser.iterate(file);
return rows;
}
は今、あなたは、このようにあなたの方法を使用することができます。
public static void main(String... args) {
IterableResult<String[], ParsingContext> rows = readCSV("c:/path/to/input.csv");
try {
for (String[] row : rows) {
//process the rows however you want
}
} finally {
//the parser closes itself but in case any errors processing the rows (outside of the control of the iterator), close the parser.
rows.getContext().stop();
}
}
これは、あなたがパーサーを使用する方法のほんの一例ですが、そこにありますそれを使用する多くの異なる方法。
今書き込みのために、あなたがこれを行うことができます:
public static void main(String... args) {
//this is your output file
File output = new File("c:/path/to/output.csv");
//configure the writer if you need to
CsvWriterSettings settings = new CsvWriterSettings();
//create the writer. Here we write to a file
CsvWriter writer = new CsvWriter(output, settings);
//get the row iterator
IterableResult<String[], ParsingContext> rows = readCSV("c:/temp");
try {
//do whatever you need to the rows here
for (String[] row : rows) {
//then write it each one to the output.
writer.writeRow(row);
}
} finally {
//cleanup
rows.getContext().stop();
writer.close();
}
}
をあなたが望むすべては、データを読み、それを修正し、戻って別のファイルにそれを書くことであるならば、あなたはちょうどこの操作を行うことができます。
public static void main(String... args) throws IOException {
CsvParserSettings parserSettings = new CsvParserSettings();
parserSettings.setProcessor(new AbstractRowProcessor() {
@Override
public void rowProcessed(String[] row, ParsingContext context) {
//modify the row data here.
}
});
CsvWriterSettings writerSettings = new CsvWriterSettings();
CsvRoutines routines = new CsvRoutines(parserSettings, writerSettings);
FileReader input = new FileReader("c:/path/to/input.csv");
FileWriter output = new FileWriter("c:/path/to/output.csv");
routines.parseAndWrite(input, output);
}
これが役に立ちます。
免責事項:私はこの本の著者です。オープンソースで無料(Apache 2.0ライセンス)です。
100,000行のデータセット全体をメモリにロードしようとしています。ヒープサイズをデータセットの予想サイズよりも大きくするか、プログラムを変更してすべてのデータを一度にロードしないようにします。 –
プログラムにcsvファイル全体を保存しないでください。なぜCSVを読んでいるのですか?あなたはデータを読み込むことで何をするつもりですか? –
@JimGarrisonもし私のヒープサイズかプログラムが問題だったのか分かりませんでした。ありがとう – Moley