Конвертировать zip в магазине компрессионные



У меня есть zip-файл file.zip, который сжат. Есть ли способ изменить уровень сжатия файла для хранения (без сжатия).



Я написал и попробовал следующий код, и он работает, но я буду запускать его в среде, где память и хранилище будут ограничены, и может не хватить места. Я использую библиотеку zip4j.



Этот код извлекает входной zip-файл в папку,а затем перезаписывает его с уровнем сжатия хранилища. Проблема с этим заключается в том, что в какой-то момент выполнения в хранилище есть 3 копии zip, что является проблемой, поскольку пространство является ограничением.



try {
String zip = "input.zip";
final ZipFile zipFile = new ZipFile(zip);
zipFile.extractAll("dir");
File file = new File("dir");
ZipParameters params = new ZipParameters();
params.setCompressionMethod(Zip4jConstants.COMP_STORE);
params.setIncludeRootFolder(false);

ZipFile output = new ZipFile(new File("out.zip"));

output.addFolder(file, params);
file.delete();
return "Done";
} catch (Exception e) {
e.printStackTrace();
return "Error";
}


Итак, есть ли предложения по другому подходу к этой проблеме? Или, может быть, некоторые оптимизации скорости или памяти для моего текущего кода?

576   2  

2 ответов:

В качестве альтернативы мы можем читать файлы из zip один за другим в памяти или во временный файл, как здесь

    ZipInputStream is = ...
    ZipOutputStream os = ...
    os.setMethod(ZipOutputStream.STORED);
    int bSize = ... calculate max available size 
    byte[] buf = new byte[bSize];
    for (ZipEntry e; (e = is.getNextEntry()) != null;) {
        ZipEntry e2 = new ZipEntry(e.getName());
        e2.setMethod(ZipEntry.STORED);
        int n = is.read(buf);
        if (is.read() == -1) {
            // in memory
            e2.setSize(n);
            e2.setCompressedSize(n);
            CRC32 crc = new CRC32();
            crc.update(buf, 0, n);
            e2.setCrc(crc.getValue());
            os.putNextEntry(e2);
            os.write(buf, 0, n);
            is.closeEntry();
            os.closeEntry();
        } else {
            // use tmp file
        }
    }

Считывание в памяти должно быть быстрее

Я, наконец, получил его через несколько часов, играя с входными потоками.

try {
            final ZipFile zipFile = new ZipFile("input.zip");
            File output = new File("out.zip");
            byte[] read = new byte[1024];
            ZipInputStream zis = new ZipInputStream(new FileInputStream(zip));
            ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(output));
            ZipEntry ze;
            zos.setLevel(ZipOutputStream.STORED);
            zos.setMethod(ZipOutputStream.STORED);
            while((ze = zis.getNextEntry()) != null) {
                int l;
                zos.putNextEntry(ze);
                System.out.println("WRITING:  " + ze.getName());
                while((l = zis.read(read)) > 0) {
                    zos.write(read, 0, l);
                }
                zos.closeEntry();
            }
            zis.close();
            zos.close();
            return "Done";
        } catch (Exception e) {
            e.printStackTrace();
            return "Error";
        }
Большое спасибо за ваш ответ Евгений Дорофеев, я буквально только что получил свой ответ, когда прочитал ваш! Однако я предпочитаю свой метод, поскольку он занимает не более 1 МБ памяти (я прав?). Кроме того, я попытался выполнить ваш код, и был передан только первый файл во входном zip-файле.

Comments

    Ничего не найдено.