当前位置: 代码迷 >> java >> 读取和处理具有5000万行(8GB)的大文件的最佳方法。 POJO创建后将其存储在Mongo DB中
  详细解决方案

读取和处理具有5000万行(8GB)的大文件的最佳方法。 POJO创建后将其存储在Mongo DB中

热度:83   发布时间:2023-07-27 09:13:29.0
ListIterator it= FileUtils.lineIterator(bigFile);
List<String> rows = new ArrayList<String>();
//Iterate and add lines to list
while(it.hasNext){
    rows.add(it.next())// Exception1 
}
//ExecutorService to Iterate a chunk of 20K rows 
// In Executor create do validations and create pojo List
// exeutor service to iterate Pojo list and save 20k chunk pojo in mongo db

问题/例外:
1.无法创建名为行的列表,GetoutOfMemory堆异常。
2.如果我不创建列表并处理每一行并存储在mongo中。 这将花费大量时间,并且还可能导致其他异常。
读取和处理如此大文件的最佳方法是什么?

2 GB的字节将是String两倍,通常String将包含char[]并且char是两个字节的UTF-16值。

最好是进行一些压缩,如前所述,压缩文件的20 KB块。 还可以为应用程序提供更多内存-DXmax=2g

您的代码假定大文件是纯文本(或HTML或SQL转储或日志文件)。

我已经完成了基于行的压缩(效果不是很好,即使对于空行也是如此)。

Path path = Paths.get(bigFile); // String bigFile
Path path = bigFile.toPath(); // File bigFile
Charset charset = Charset.defaultCharset(); // Or whatever the charset is.
List<byte[]> compressedLines = Files.lines(path, charset)
    .map(line -> compress(line)) // Or compress(line + "\n")
    .collect(Collectors.toList());


byte[] compress(String s) {
    byte[] content = s.getBytes(StandardCharsets.UTF_8);
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    try (GZipOutputStream out = new GZipOutputStream(baos)) {
        out.write(content);
    }
    return baos.toByteArray();
}

String decompress(byte[] compressed) {
    ByteArrayInputStream bais = new ByteArrayInputStream(compressed);
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    try (GZipInputStream in = new GZipInputStream(bais)) {
        byte[] buf = new byte[128];
        for (;;) {
            int nread = in.read(buf, 0, buf.length);
            if (nread <= 0) {
                break;
            }
            baos.write(buf, 0, nread);
        }
    }
    return new String(baos.toByteArray(), StandardCharsets.UTF_8);
}

这可能不是最佳的解决方案。

  相关解决方案