zip4j:从输入流(一个ZIP文件的blob输入流)中提取受密码保护的文件

5
我有一个数据库,包含了BLOB和一个密码保护的ZIP文件。通常情况下,我会使用标准的File对象来处理。
        File zipFile = new File("C:\\file.zip");        
        net.lingala.zip4j.core.ZipFile table = new net.lingala.zip4j.core.ZipFile(zipFile);                    
        if (table.isEncrypted())
            table.setPassword(password);           

        net.lingala.zip4j.model.FileHeader entry = table.getFileHeader("file_inside_the_zip.txt");
        return table.getInputStream(entry); //Decrypted inputsteam!

我的问题是,如何在不使用临时文件的情况下实现这样的功能,并纯粹地获取blob的输入流。到目前为止,我有类似于以下内容:

InputStream zipStream = getFileFromDataBase("stuff.zip");
//This point forward I have to save zipStream as a temporary file and use the traditional code above

你解决了吗?我有一个类似的问题 - 想要提取 getContentResolver().openInputStream(uri)。 - Alex
我怀疑目前可能不太可能……以 net.lingala.zip4j.core.ZipFile#readZipInfo为例,它纯粹基于文件而非流来实现。但由于Zip4J是开源的,可以进行扩展……但可能需要一些工作。 - Alex
4个回答

2

你可以使用net.lingala.zip4j.io.inputstream.ZipInputStream来实现它

(假设有一个byte[]类型的zipFile和一个String类型的password)

String zipPassword = "abcabc";

ZipInputStream innerZip = new ZipInputStream(new ByteArrayInputStream(zipFile), zipPassword.toCharArray());

那么你可以循环遍历你的非受保护zip文件

File zip = null;
while ((zipEntry = zipIs.getNextEntry()) != null) {
  zip = new File(file.getAbsolutePath(), zipEntry.getFileName());
  ....
}


1
我在处理Hadoop文件系统(HDFS)中的受密码保护的压缩文件时遇到了同样的问题。HDFS不知道文件对象。
以下是使用zip4j适用于我的方法:
        Configuration conf = new Configuration();
        FileSystem fs = FileSystem.get(conf);
        Path hdfsReadPath = new Path(zipFilePath); // like "hdfs://master/dir/sub/data/the.zip"

        FSDataInputStream inStream =   fs.open(hdfsReadPath);
        ZipInputStream zipInputStream = new ZipInputStream(inStream, passWord.toCharArray());

        LocalFileHeader zipEntry = null;

        BufferedReader reader = new BufferedReader(new InputStreamReader(zipInputStream));
        while ((zipEntry = zipInputStream.getNextEntry()) != null ) {
            String entryName = zipEntry.getFileName();
            System.out.println(entryName);
            if (!zipEntry.isDirectory()) {
                String line;
                while ((line = reader.readLine()) != null) {
                    //process the line
                }
            }
        }
        reader.close();
        zipInputStream.close();

1
public void extractWithZipInputStream(File zipFile, char[] password) throws IOException {
    LocalFileHeader localFileHeader;
    int readLen;
    byte[] readBuffer = new byte[4096];

    InputStream inputStream = new FileInputStream(zipFile);
    try (ZipInputStream zipInputStream = new ZipInputStream(inputStream, password)) {
      while ((localFileHeader = zipInputStream.getNextEntry()) != null) {
        File extractedFile = new File(localFileHeader.getFileName());
        try (OutputStream outputStream = new FileOutputStream(extractedFile)) {
          while ((readLen = zipInputStream.read(readBuffer)) != -1) {
            outputStream.write(readBuffer, 0, readLen);
          }
        }
      }
    }
  }

这个方法需要根据您的需求进行修改。例如,您可能需要更改输出位置。我已经尝试过了,它可以正常工作。为了更好地理解,请参见 https://github.com/srikanth-lingala/zip4j


0

看起来确实是这样。我在zip4j官方论坛上进行了详尽的搜索,但没有找到任何相关信息。 - jyonkheel
请注意,此方法无法处理AES加密。 - Hossein Shahdoost

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接