【问题标题】:zip4J exception un-zipping password protected zip filezip4J 异常解压缩密码保护的 zip 文件
【发布时间】:2021-08-25 00:48:08
【问题描述】:

我的任务是使用涉及的开源 'zip4jlibrary for creating and unzipping of password-protected zip files. Method parameters will bebyte[]of file content and password and it should return a byte array as output (unzipped or zipped content), noFile system`。我尝试了以下抛出的代码段 'net.lingala.zip4j.exception.ZipException:文件不存在:\test\Test.txt' 在行“zipFile.addFiles(filesToAdd, zipParameters);”我在这里缺少什么? 线程“主”net.lingala.zip4j.exception.ZipException 中的异常:文件不存在:\test\ZipThis.txt 在 net.lingala.zip4j.util.FileUtils.assertFileExists(FileUtils.java:526) 在 net.lingala.zip4j.util.FileUtils.assertFilesExist(FileUtils.java:359) 在 net.lingala.zip4j.tasks.AbstractAddFileToZipTask.addFilesToZip(AbstractAddFileToZipTask.java:62) 在 net.lingala.zip4j.tasks.AddFilesToZipTask.executeTask(AddFilesToZipTask.java:27) 在 net.lingala.zip4j.tasks.AddFilesToZipTask.executeTask(AddFilesToZipTask.java:15) 在 net.lingala.zip4j.tasks.AsyncZipTask.performTaskWithErrorHandling(AsyncZipTask.java:51) 在 net.lingala.zip4j.tasks.AsyncZipTask.execute(AsyncZipTask.java:45) 在 net.lingala.zip4j.ZipFile.addFiles(ZipFile.java:318) 在 net.lingala.zip4j.ZipFile.addFile(ZipFile.java:275)



public class ExtractZip {

    public static byte[] extractWithZipInputStream(byte[] inputArr, char[] password) {
        LocalFileHeader localFileHeader;
        int readLen;
        InputStream byteStream = new ByteArrayInputStream(inputArr);
        byte[] readBuffer = new byte[4096];
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ZipInputStream zipInputStream = new ZipInputStream(byteStream, password);

        try {
            while ((localFileHeader = zipInputStream.getNextEntry()) != null) {
                while ((readLen = zipInputStream.read(readBuffer)) != -1) {
                    bos.write(readBuffer, 0, readLen);
                }
                break;
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                bos.close();
            } catch (Exception e) {
            }
            try {
                zipInputStream.close();
            } catch (Exception e) {
            }
        }
        return bos.toByteArray();
    }

    public static void main(String[] args) {
        FileOutputStream fos;
        byte[] inputBuffer = new byte[1024];

        try {
            ZipParameters zipParameters = new ZipParameters();
            zipParameters.setEncryptFiles(true);
            zipParameters.setEncryptionMethod(EncryptionMethod.ZIP_STANDARD);
            List<File> filesToAdd = Arrays.asList(new File("/test/ZipThis.txt"));
            ZipFile zipFile = new ZipFile("/test/Template_Zip.zip", "abc123".toCharArray());
            zipFile.addFiles(filesToAdd, zipParameters);
            inputBuffer = Files.readAllBytes(Paths.get("/test/Template_Zip.zip"));
            byte[] outputArr = ExtractZip.extractWithZipInputStream(inputBuffer, "abc123".toCharArray());

            //Test if you can create a file using with this byte array
            File unZipped = new File("/test/unzipped/temp");
            fos = new FileOutputStream(unZipped);
            fos.write(outputArr[0]);
            fos.flush();
            fos.close();
            zipFile.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

【问题讨论】:

    标签: java zip4j


    【解决方案1】:

    我觉得不错。只需尝试设置 absolute path 而不是相对的。例如

    ZipFile zipFile = new ZipFile("c:/test/Template_Zip.zip", "abc123".toCharArray());
    

    所有其他这样的地方也是如此。我想你的问题会消失的。

    P.S.最好使用try with resources 而不是你所做的。


    import net.lingala.zip4j.ZipFile;
    import net.lingala.zip4j.io.inputstream.ZipInputStream;
    import net.lingala.zip4j.model.LocalFileHeader;
    import net.lingala.zip4j.model.ZipParameters;
    import net.lingala.zip4j.model.enums.EncryptionMethod;
    
    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.nio.file.Files;
    import java.nio.file.Paths;
    import java.util.Arrays;
    import java.util.List;
    
    public class ExtractZip {
    
        public static byte[] extractWithZipInputStream(byte[] buf, char[] password) throws IOException {
            try (InputStream byteStream = new ByteArrayInputStream(buf);
                 ZipInputStream zipInputStream = new ZipInputStream(byteStream, password);
                 ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
    
                LocalFileHeader localFileHeader = zipInputStream.getNextEntry();
    
                if (localFileHeader == null)
                    return new byte[0];
    
                int readLen;
                byte[] readBuffer = new byte[4096];
    
                while ((readLen = zipInputStream.read(readBuffer)) != -1) {
                    bos.write(readBuffer, 0, readLen);
                }
    
                return bos.toByteArray();
            }
        }
    
        public static void main(String[] args) throws IOException {
            ZipParameters zipParameters = new ZipParameters();
            zipParameters.setEncryptFiles(true);
            zipParameters.setEncryptionMethod(EncryptionMethod.ZIP_STANDARD);
            List<File> filesToAdd = Arrays.asList(new File("e:/foo.txt"));
            ZipFile zipFile = new ZipFile("e:/Template_Zip.zip", "abc123".toCharArray());
            zipFile.addFiles(filesToAdd, zipParameters);
            byte[] buf = Files.readAllBytes(Paths.get("e:/Template_Zip.zip"));
            buf = extractWithZipInputStream(buf, "abc123".toCharArray());
    
            try (FileOutputStream fos = new FileOutputStream(new File("e:/fooZip.txt"))) {
                fos.write(buf);
            }
        }
    
    }
    

    (广告)尝试另一个库 - zip4jvm。你会发现它更容易使用。

    【讨论】:

    • 我用绝对路径试过了,还是一样的异常
    • @user1902124 奇怪。试试 zip4jvm。
    • zip4jvm 可以用于密码保护的 zip 文件吗?我也只是得到压缩内容的字节数组和密码。
    • 是的,请参阅带有示例的 GitHub 链接。