我想读一个巨大的csv文件。我们通常使用superCSV来解析文件。在这种特殊情况下,文件很大,并且由于显而易见的原因,总会出现内存不足的问题。
最初的想法是将文件读取为块,但我不确定这是否适用于superCSV,因为当我对文件进行分块时,只有第一个块具有头值并且将被加载到CSV bean中,而其他块没有标头值,我觉得它可能会抛出异常。所以
a)我想知道我的思维过程是否正确 b)是否还有其他方法可以解决这个问题。
所以我的主要问题是
superCSV是否具有处理大型csv文件的能力,我看到superCSV通过BufferedReader读取文档。但是我不知道缓冲区的大小是什么,我们可以根据我们的要求进行更改吗?
@Gilbert Le Blanc我根据你的建议试图分成更小的块,但是要花费很长时间将大文件分解成更小的块。这是我写的代码。
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.LineNumberReader;
public class TestFileSplit {
public static void main(String[] args) {
LineNumberReader lnr = null;
try {
//RandomAccessFile input = new RandomAccessFile("", "r");
File file = new File("C:\\Blah\\largetextfile.txt");
lnr = new LineNumberReader(new FileReader(file), 1024);
String line = "";
String header = null;
int noOfLines = 100000;
int i = 1;
boolean chunkedFiles = new File("C:\\Blah\\chunks").mkdir();
if(chunkedFiles){
while((line = lnr.readLine()) != null) {
if(lnr.getLineNumber() == 1) {
header = line;
continue;
}
else {
// a new chunk file is created for every 100000 records
if((lnr.getLineNumber()%noOfLines)==0){
i = i+1;
}
File chunkedFile = new File("C:\\Blah\\chunks\\" + file.getName().substring(0,file.getName().indexOf(".")) + "_" + i + ".txt");
// if the file does not exist create it and add the header as the first row
if (!chunkedFile.exists()) {
file.createNewFile();
FileWriter fw = new FileWriter(chunkedFile.getAbsoluteFile(), true);
BufferedWriter bw = new BufferedWriter(fw);
bw.write(header);
bw.newLine();
bw.close();
fw.close();
}
FileWriter fw = new FileWriter(chunkedFile.getAbsoluteFile(), true);
BufferedWriter bw = new BufferedWriter(fw);
bw.write(line);
bw.newLine();
bw.close();
fw.close();
}
}
}
lnr.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
}
}
}
答案 0 :(得分:2)
您可以在解析器java类本身中定义头。这样,您就不需要CSV文件中的标题行。
// only map the first 3 columns - setting header elements to null means those columns are ignored
final String[] header = new String[] { "customerNo", "firstName", "lastName", null, null, null, null, null, null, null };
beanReader.read(CustomerBean.class, header)
或
您也可以使用SuperCSV api的dozer扩展。
答案 1 :(得分:1)
我不确定问题是什么。一次读取一行作为bean需要大致恒定的内存消耗。如果您一次存储所有读取对象,那么您的内存不足。但是这个超级csv的错是怎么回事?