我有以下两个读取csv文件的实现,有问题的csv文件不是那么大(5兆字节)。
第一个实现是使用openCSV,第二个是使用stringTokenizer。
第一个导致内存不足错误,即使我将java最大堆内存提升到1G(Xmx),虽然StringTokenizer实现不健壮,但我别无选择,因为我需要将csv文件读入内存
我不明白为什么openCSV版本在csv文件的小尺寸(它有200k行,但只有大约5m文件大小)的情况下会消耗这么多内存。什么是openCSV读者,这需要如此多的内存? StringTokenizer版本很快就会通过它。
这是openCSV实现抛出的错误:
Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded
at java.util.Arrays.copyOfRange(Arrays.java:3209)
at java.lang.String.<init>(String.java:215)
at java.lang.StringBuilder.toString(StringBuilder.java:430)
at au.com.bytecode.opencsv.CSVParser.parseLine(Unknown Source)
at au.com.bytecode.opencsv.CSVParser.parseLineMulti(Unknown Source)
at au.com.bytecode.opencsv.CSVReader.readNext(Unknown Source)
private List<String[]> parseCSV(File f) {
List<String[]>res=new Vector<String[]>();
CSVReader reader=null;
try{
reader = new CSVReader(new BufferedReader(new FileReader(f)));
String [] nextLine;
while ((nextLine = reader.readNext()) != null) {
for(int i=0;i<nextLine.length;i++)if(nextLine[i]!=null)nextLine[i]=nextLine[i].trim();
res.add(nextLine);
}
}catch(IOException exp){
exp.printStackTrace();
}finally{
if(reader!=null)try {
reader.close();
} catch (IOException ex) {
Logger.getLogger(DataStream2.class.getName()).log(Level.SEVERE, null, ex);
}
}
return res;
}
private List<String[]> parseCSV(File f) {
List<String[]>res=new Vector<String[]>();
BufferedReader br=null;
try{
br = new BufferedReader(new FileReader(f));
String line =null;
while((line=br.readLine())!=null){
StringTokenizer st=new StringTokenizer(",");
String[]cur=new String[st.countTokens()];
for(int i=0;i<cur.length;i++){
cur[i]=st.nextToken().trim();
}
res.add(cur);
}
}catch(IOException exp){
exp.printStackTrace();
}
finally{
if(br!=null)try {
br.close();
} catch (IOException ex) {
Logger.getLogger(DataStream2.class.getName()).log(Level.SEVERE, null, ex);
}
}
return res;
}
答案 0 :(得分:0)
不太可能,但我猜你的输入数据可能会触发opencsv库中的一个错误,可能会导致它陷入循环中。
opencsv的下载提供了源代码和库,因此您应该能够自己调试代码。
由于stacktrace没有显示opencsv代码的行号,我猜你需要改变构建脚本中的javac目标以包含“debug = true”,以启用代码的调试编译。
答案 1 :(得分:0)
事实证明,StringTokenizer版本有一个错误,因此两个版本都没有内存。
答案 2 :(得分:0)
Apache Solr使用commons-csv所以我建议您尝试一下。索尔使用它是一个很大的认可。