java - 使用superCSV读取一个80GB的大文本文件

标签 java java.nio.file supercsv

我想读取一个巨大的 csv 文件。我们一般使用 superCSV 来解析文件。在这种特殊情况下,文件很大,并且由于显而易见的原因总是会出现内存不足的问题。

最初的想法是将文件作为 block 读取,但我不确定这是否适用于 superCSV,因为当我将文件分块时,只有第一个 block 具有 header 值并将加载到 CSV bean 中,而其他 block 没有 header 值,我觉得它可能会抛出异常。所以

a) 我想知道我的思维过程是否正确
b) 有没有其他方法可以解决这个问题。

所以我的主要问题是

superCSV 是否具有处理大型 csv 文件的能力,我看到 superCSV 通过 BufferedReader 读取文档。但是我不知道缓冲区的大小是多少,我们可以根据需要更改它吗?

@Gilbert Le Blanc我已经尝试按照您的建议拆分成更小的 block ,但是将大文件拆分成更小的 block 需要很长时间。这是我为此编写的代码。

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 {
    }
}
}   

最佳答案

您可以在解析器 java 类本身中定义 header 。这样,您就不需要 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 扩展。

关于java - 使用superCSV读取一个80GB的大文本文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12645967/

相关文章:

java - 我应该在 HTTPClass 中的哪里实现这个 Jackson Root Element 代码?

java - Files.getLastModifiedTime() 是否泄漏内存?

java - SuperCSV Joda 时间 LocalDate 单元处理器接受多种日期格式

java - 使用 SuperCSV 更改 header 值

java - Spring框架中@Import和@ImportResource注解的使用有什么区别?

java - 二进制 XML 文件行 #0 : Error inflating class ImageView

java - 我应该在 TDD 中使用 lambda 吗?

java - Jackson 如何自动反序列化 java.nio.file.Path?

java - 非法参数异常 : URI is not hierarchical when calling existing folder

java - 十进制格式 "Multiple decimal separators in pattern"