提取 SFX 7-Zip

Posted

技术标签:

【中文标题】提取 SFX 7-Zip【英文标题】:Extracting SFX 7-Zip 【发布时间】:2016-02-27 14:03:37 【问题描述】:

我想从.zip 文件中提取两个特定文件。我尝试了以下库:

ZipFile zipFile = new ZipFile("myZip.zip");

结果:

Exception in thread "main" java.util.zip.ZipException: error in opening zip file

我也试过了:

public void extract(String targetFileName) throws IOException

    OutputStream outputStream = new FileOutputStream("targetFile.foo");
    FileInputStream fileInputStream = new FileInputStream("myZip.zip");
    ZipInputStream zipInputStream = new ZipInputStream(new BufferedInputStream(fileInputStream));
    ZipEntry zipEntry;

    while ((zipEntry = zipInputStream.getNextEntry()) != null)
    
        if (zipEntry.getName().equals("targetFile.foo"))
        
            byte[] buffer = new byte[8192];
            int length;
            while ((length = zipInputStream.read(buffer)) != -1)
            
                outputStream.write(buffer, 0, length);
            
            outputStream.close();
            break;
        
    

结果: 也不例外,只是一个空的targetFile.foo 文件。

请注意,.zip 文件的类型为 SFX 7-zip,最初具有 .exe 扩展名,因此这可能是失败的原因。

【问题讨论】:

它是否适用于正则 zip 文件? 该格式与ZipInputStream 不兼容。见this answer 【参考方案1】:

与评论一样,您的库基本上不支持提取 SFX 7-Zip 文件。但是您可以将 commons compress 和 xz Libary 与快速“hack”一起使用:

import org.apache.commons.compress.archivers.sevenz.SevenZArchiveEntry;
import org.apache.commons.compress.archivers.sevenz.SevenZFile;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
...
  protected File un7zSFXFile(File file, String password)
      
        SevenZFile sevenZFile = null;
        File tempFile = new File("/tmp/" + file.getName() + ".temp");
        try
        
          FileInputStream in = new FileInputStream(file);
          /**
           * Yes this is Voodoo Code:
           * first 205824 Bytes get skipped as these is are basically the 7z-sfx-runnable.dll
           * common-compress does fail if this information is not cut away
           * ATTENTION: the amount of bytes may vary depending of the 7z Version used!
           */
          in.skip(205824);
          // EndOfVoodoCode
          tempFile.getParentFile().mkdirs();
          tempFile.createNewFile();
          FileOutputStream temp = new FileOutputStream(tempFile);
          byte[] buffer = new byte[1024];
          int length;
          while((length = in.read(buffer)) > 0)
          
            temp.write(buffer, 0, length);
          
          temp.close();
          in.close();
          LOGGER.info("prepared exefile for un7zing");
          if (password!=null) 
          sevenZFile = new SevenZFile(tempFile, password.toCharArray());
           else 
            sevenZFile = new SevenZFile(tempFile);
          
          SevenZArchiveEntry entry;
          boolean first = true;// accept only files with
          while((entry = sevenZFile.getNextEntry()))
          
            if(entry.isDirectory())
            
              continue;
            
            File curfile = new File(file.getParentFile(), entry.getName());
            File parent = curfile.getParentFile();
            if(!parent.exists())
            
              parent.mkdirs();
            
            FileOutputStream out = new FileOutputStream(curfile);
            byte[] content = new byte[(int) entry.getSize()];
            sevenZFile.read(content, 0, content.length);
            out.write(content);
            out.close();
          
        
        catch(Exception e)
                  
          throw e;
        
        finally
        
          try
          
            tempFile.delete();
            sevenZFile.close();
    
          
          catch(Exception e)
          
            LOGGER.trace("error on cloasing Stream: " + sevenZFile.getDefaultName(), e);
          
        
      

请注意,这个简单的解决方案只会解压到与 as sfx 文件所在的目录相同的目录中!

【讨论】:

以上是关于提取 SFX 7-Zip的主要内容,如果未能解决你的问题,请参考以下文章

在 SFX 存档提取时显示进度条

7-zip SFX 配置问题 [关闭]

7-Zip 文件夹中不存在 7zS.sfx

为啥解压时 sfx Sevenzipsharp '7-zip : unsupported method'?

7 Zip 提取错误:标头错误 密码错误

7-Zip 命令在 Windows 上创建和提取受密码保护的 ZIP 文件? [关闭]