Лучший способ прочитать и обработать большой файл с 50 миллионами строк (8 ГБ).После создания POJO Store в БД Монго - PullRequest
0 голосов
/ 12 февраля 2019
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. Невозможно создать список именованных строк, исключение кучи Getting outOfMemory.
2. Если я не создаю список и не обрабатываю каждую строку и не сохраняю их в монго.Это займет много времени и может привести к другим исключениям.
Каков наилучший подход для чтения и обработки такого большого файла?

1 Ответ

0 голосов
/ 12 февраля 2019

2 ГБ байтов увеличится вдвое, так как String обычно будет содержать char[], а char - это двухбайтовое значение UTF-16.

Лучше всего будет иметь некоторое сжатие, возможно, на 20Кб куски файла, как уже упоминалось.Приложению также может быть выделено больше памяти -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);
}

Возможно, это не лучшее решение, как есть.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...