распаковать огромный файл gz в Java и производительность - PullRequest
3 голосов
/ 14 февраля 2011

Я распаковываю огромный файл gz в java, файл gz составляет около 2 ГБ, а разархивированный файл - около 6 ГБ. время от времени процесс распаковки может длиться вечно (часы), иногда он заканчивается за разумное время (например, менее 10 минут или быстрее).
У меня довольно мощный блок (8 ГБ оперативной памяти, 4 процессора), есть ли способ улучшить код ниже? или использовать совершенно другую библиотеку?
Также я использовал Xms256m и Xmx4g для виртуальной машины.

public static File unzipGZ(File file, File outputDir) {
    GZIPInputStream in = null;
    OutputStream out = null;
    File target = null;
    try {
        // Open the compressed file
        in = new GZIPInputStream(new FileInputStream(file));

        // Open the output file
        target = new File(outputDir, FileUtil.stripFileExt(file.getName()));
        out = new FileOutputStream(target);

        // Transfer bytes from the compressed file to the output file
        byte[] buf = new byte[1024];
        int len;
        while ((len = in.read(buf)) > 0) {
            out.write(buf, 0, len);
        }

        // Close the file and stream
        in.close();
        out.close();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (in != null) {
            try {
                in.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        if (out != null) {
            try {
                out.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
    return target;
}

Ответы [ 3 ]

2 голосов
/ 14 февраля 2011

Я не знаю, какая буферизация применяется по умолчанию, если она есть, но вы можете попробовать обернуть как вход, так и вывод в BufferedInputStream / BufferedOutputStream. Вы также можете попробовать увеличить размер буфера - 1K - довольно маленький буфер. Экспериментируйте с разными размерами, например 16K, 64K и т. Д. Из-за них использование BufferedInputStream, конечно, не так важно.

С другой стороны, я подозреваю, что это на самом деле не проблема. Если это иногда заканчивается через 10 минут, а иногда и часами, это говорит о том, что происходит что-то очень странное. Когда это занимает очень много времени, действительно ли это прогресс? Размер выходного файла увеличивается? Это использует значительный процессор? Диск постоянно используется?

Примечание с одной стороны: когда вы закрываете in и out в блоках finally, вам не нужно делать это и в блоке try.

0 голосов
/ 14 февраля 2011

Попробуйте использовать каналы из java.nio, есть метод для передачи байтов из других файловых каналов. Тогда вам не нужно копировать их самостоятельно. И это, вероятно, будет довольно оптимизировано. См. FileInputStream.getChannel ()

0 голосов
/ 14 февраля 2011

Если у вас 8 гигабайт оперативной памяти, а входной файл занимает 2 гигабайта, вы можете попытаться использовать файл с отображенной памятью. Здесь - пример того, как это сделать.

...