Получение исключения «отрицательное время» при распаковке zip-файла с zip4j - PullRequest
0 голосов
/ 12 ноября 2018

Я использую zip4j для извлечения zip файлов.Для многих пользователей это работает нормально, но пользователь Windows 8 получает следующее исключение:

net.lingala.zip4j.exception.ZipException: net.lingala.zip4j.exception.ZipException: java.lang.IllegalArgumentException: Negative time
    at net.lingala.zip4j.unzip.Unzip.initExtractFile(Unzip.java:163)
    at net.lingala.zip4j.unzip.Unzip.initExtractAll(Unzip.java:83)
    at net.lingala.zip4j.unzip.Unzip.extractAll(Unzip.java:73)
    at net.lingala.zip4j.core.ZipFile.extractAll(ZipFile.java:488)
    at net.lingala.zip4j.core.ZipFile.extractAll(ZipFile.java:451)
    ...

Кажется, что отрицательное время вызвано файлом в файловой системе, имеющим отрицательное время и / илиошибкой JVM .Кто-нибудь знает, как решить эту проблему, поскольку это довольно странно и не связано с моим использованием API, я полагаю.

zip4j не поддерживается с 2013, поэтому я бы не сталбудьте удивлены, если в ней есть какие-то ошибки, но просто нет более способной zip библиотеки без шаблонного шаблона, кроме JDK.Однако мне нужна поддержка zip-файла, защищенного паролем, и , который не поддерживается JDK .

Установка JDK 11 и использование его для запуска приложения не решают проблему, но это былостоит попробовать.

1 Ответ

0 голосов
/ 12 ноября 2018

Проведя еще какое-то исследование, я нашел 7-Zip-JBinding:

<dependency>
    <groupId>net.sf.sevenzipjbinding</groupId>
    <artifactId>sevenzipjbinding</artifactId>
    <version>LATEST</version>
</dependency>
<dependency>
    <groupId>net.sf.sevenzipjbinding</groupId>
    <artifactId>sevenzipjbinding-all-platforms</artifactId>
    <version>LATEST</version>
</dependency>

Следующий код может быть использован для извлечения защищенного паролем zip-файла:

public static void unzipUsing7Zip(String zipFilePath,
                                   String destinationDirectory,
                                   String password) throws IOException
{
    try (val randomAccessFile = new RandomAccessFile(zipFilePath, "r");
         val randomAccessFileInStream = new RandomAccessFileInStream(randomAccessFile);
         val inArchive = openInArchive(null, randomAccessFileInStream))
    {
        val simpleInArchive = inArchive.getSimpleInterface();
        val archiveItems = simpleInArchive.getArchiveItems();

        for (val archiveItem : archiveItems)
        {
            if (!archiveItem.isFolder())
            {
                val archiveItemPath = archiveItem.getPath();
                val targetFilePath = destinationDirectory + separator + archiveItemPath;

                try (val fileOutputStream = new FileOutputStream(targetFilePath))
                {
                    archiveItem.extractSlow(data ->
                    {
                        try
                        {
                            if (archiveItemPath.indexOf(separator) > 0)
                            {
                                // Create parent folder(s)
                                val lastSeparatorIndex = archiveItemPath.lastIndexOf(separator);
                                val path = destinationDirectory + separator + archiveItemPath.substring(0, lastSeparatorIndex);
                                createDirectories(Paths.get(path));
                            }

                            fileOutputStream.write(data);
                        } catch (Exception exception)
                        {
                            exception.printStackTrace();
                        }

                        return data.length;
                    }, password);
                }
            }
        }
    }
}

На основе здесь , но очищен и добавлен реальный код извлечения файла с помощью FileOutputStream.

Дополнительное примечание: val происходит от lombok конечно.

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>LATEST</version>
    <scope>provided</scope>
</dependency>
...