Если вы используете Linux, и вы можете сначала запустить CSV через скрипт, то вы можете использовать «split»:
$ split -l 100000 big.csv small-
Это создает файлы с именем small-aa, small-ab , small-a c ... Чтобы переименовать их в csv, если необходимо:
$ for a in small-*; do
mv $a $a.csv; # rename split files to .csv
java MyCSVProcessor $a.csv; # or just process them anyways
done
Попробуйте это для дополнительных опций:
$ split -h
-a –suffix-length=N use suffixes of length N (default 2)
-b –bytes=SIZE put SIZE bytes per output file
-C –line-bytes=SIZE put at most SIZE bytes of lines per output file
-d –numeric-suffixes use numeric suffixes instead of alphabetic
-l –lines=NUMBER put NUMBER lines per output file
Это, однако, плохое смягчение для вашего проблема - причина того, что вашему модулю чтения CSV не хватает памяти, заключается в том, что он либо читает весь файл в память перед его разбиением, либо делает это и сохраняет обработанный вывод в памяти. Чтобы сделать ваш код более переносимым и универсально работоспособным, вам следует рассмотреть возможность обработки по одной строке за раз - и разбивать ввод самостоятельно, построчно. (С https://stackabuse.com/reading-and-writing-csvs-in-java/)
BufferedReader csvReader = new BufferedReader(new FileReader(pathToCsv));
while ((row = csvReader.readLine()) != null) {
String[] data = row.split(",");
// do something with the data
}
csvReader.close();
Предостережение с приведенным выше кодом заключается в том, что запятые в кавычках будут просто рассматриваться как новые столбцы - вам придется добавить дополнительную обработку, если ваши данные CSV содержит кавычки.
Конечно, если вы действительно хотите использовать существующий код и просто хотите разделить файл, вы можете изменить приведенное выше:
import java.io.*;
public class split {
static String CSVFile="test.csv";
static String row;
static BufferedReader csvReader;
static PrintWriter csvWriter;
public static void main(String[] args) throws IOException {
csvReader = new BufferedReader(new FileReader(CSVFile));
int line = 0;
while ((row = csvReader.readLine()) != null) {
if (line % 100000 == 0) { // maximum lines per file
if (line>0) { csvWriter.close(); }
csvWriter = new PrintWriter("cut-"+Integer.toString(line)+CSVFile);
}
csvWriter.println(row);
// String[] data = row.split(",");
// do something with the data
line++;
}
csvWriter.close();
csvReader.close();
}
}
Я выбрал PrintWriter вместо FileWriter или BufferedWriter, потому что он автоматически печатает соответствующие новые строки - и я предполагаю, что он буферизован ... Я ничего не писал за Java за 20 лет, так что держу пари, что вы можете улучшить вышеперечисленное.