Advertisement
treaz

7zip extract specific files

Sep 2nd, 2013
60
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 7.14 KB | None | 0 0
  1. import com.aimms.pro.exceptions.ExtractionException;
  2. import java.io.File;
  3. import java.io.FileNotFoundException;
  4. import java.io.FileOutputStream;
  5. import java.io.IOException;
  6. import java.io.OutputStream;
  7. import java.io.RandomAccessFile;
  8. import java.util.ArrayList;
  9. import java.util.List;
  10.  
  11. import net.sf.sevenzipjbinding.ExtractAskMode;
  12. import net.sf.sevenzipjbinding.ExtractOperationResult;
  13. import net.sf.sevenzipjbinding.IArchiveExtractCallback;
  14. import net.sf.sevenzipjbinding.ISequentialOutStream;
  15. import net.sf.sevenzipjbinding.ISevenZipInArchive;
  16. import net.sf.sevenzipjbinding.PropID;
  17. import net.sf.sevenzipjbinding.SevenZip;
  18. import net.sf.sevenzipjbinding.SevenZipException;
  19. import net.sf.sevenzipjbinding.impl.RandomAccessFileInStream;
  20. import org.slf4j.Logger;
  21. import org.slf4j.LoggerFactory;
  22.  
  23. /**
  24.  * Class taken from https://gist.github.com/borisbrodski/6120309
  25.  *
  26.  * @author Horia
  27.  */
  28. public class ArchiveExtractorHelper {
  29.  
  30.     private final Logger LOG = LoggerFactory.getLogger(getClass());
  31.  
  32.     class ExtractCallback implements IArchiveExtractCallback {
  33.  
  34.         private ISevenZipInArchive inArchive;
  35.         private int index;
  36.         private Boolean skipExtraction;
  37.         private OutputStream outputStream;
  38.         private File file;
  39.  
  40.         ExtractCallback(ISevenZipInArchive inArchive) {
  41.             this.inArchive = inArchive;
  42.         }
  43.  
  44.         @Override
  45.         public void setTotal(long total) throws SevenZipException {
  46.         }
  47.  
  48.         @Override
  49.         public void setCompleted(long completeValue) throws SevenZipException {
  50.         }
  51.  
  52.         @Override
  53.         public ISequentialOutStream getStream(int index,
  54.                 ExtractAskMode extractAskMode) throws SevenZipException {
  55.  
  56.             closeOutputStream();
  57.  
  58.             this.index = index;
  59.             skipExtraction = (Boolean) inArchive.getProperty(index, PropID.IS_FOLDER);
  60.             String path = (String) inArchive.getProperty(index, PropID.PATH);
  61.             file = new File(outputDirectoryFile, path);
  62.             if (extractAskMode != ExtractAskMode.EXTRACT) {
  63.                 if (skipExtraction) {
  64.                     createDirectory(file);
  65.                 }
  66.                 return null;
  67.             }
  68.  
  69.             createDirectory(file.getParentFile());
  70.  
  71.             try {
  72.                 outputStream = new FileOutputStream(file);
  73.             } catch (FileNotFoundException e) {
  74.                 throw new SevenZipException("Error opening file: "
  75.                         + file.getAbsolutePath(), e);
  76.             }
  77.  
  78.             return new ISequentialOutStream() {
  79.                 @Override
  80.                 public int write(byte[] data) throws SevenZipException {
  81.                     try {
  82.                         outputStream.write(data);
  83.                     } catch (IOException e) {
  84.                         throw new SevenZipException("Error writing to file: "
  85.                                 + file.getAbsolutePath());
  86.                     }
  87.                     return data.length; // Return amount of proceed data
  88.                 }
  89.             };
  90.         }
  91.  
  92.         private void createDirectory(File parentFile) throws SevenZipException {
  93.             if (!parentFile.exists()) {
  94.                 if (!parentFile.mkdirs()) {
  95.                     throw new SevenZipException("Error creating directory: "
  96.                             + parentFile.getAbsolutePath());
  97.                 }
  98.             }
  99.         }
  100.  
  101.         private void closeOutputStream() throws SevenZipException {
  102.             if (outputStream != null) {
  103.                 try {
  104.                     outputStream.close();
  105.                 } catch (IOException e) {
  106.                     throw new SevenZipException("Error closing file: "
  107.                             + file.getAbsolutePath());
  108.                 }
  109.             }
  110.         }
  111.  
  112.         @Override
  113.         public void prepareOperation(ExtractAskMode extractAskMode)
  114.                 throws SevenZipException {
  115.         }
  116.  
  117.         @Override
  118.         public void setOperationResult(
  119.                 ExtractOperationResult extractOperationResult)
  120.                 throws SevenZipException {
  121.             if (skipExtraction) {
  122.                 return;
  123.             }
  124.             if (extractOperationResult != ExtractOperationResult.OK) {
  125.                 String path = (String) inArchive.getProperty(index, PropID.PATH);
  126.                 throw new SevenZipException("Extraction error: " + path);
  127.             } else {
  128.             }
  129.         }
  130.     }
  131.     private File archive;
  132.     private String outputDirectory;
  133.     private File outputDirectoryFile;
  134.  
  135.     public ArchiveExtractorHelper(File archive, String outputDirectory) {
  136.         this.archive = archive;
  137.         this.outputDirectory = outputDirectory;
  138.     }
  139.  
  140.     public void extract(String... fileNames) throws ExtractionException {
  141.         checkArchiveFile();
  142.         prepareOutputDirectory();
  143.         extractAllArchive(fileNames);
  144.     }
  145.  
  146.     private void prepareOutputDirectory() throws ExtractionException {
  147.         outputDirectoryFile = new File(outputDirectory);
  148.         if (!outputDirectoryFile.exists()) {
  149.             outputDirectoryFile.mkdirs();
  150.         } else {
  151.             if (outputDirectoryFile.list().length != 0) {
  152.                 LOG.info("Output directory not empty: "
  153.                         + outputDirectory);
  154.             }
  155.         }
  156.     }
  157.  
  158.     private void checkArchiveFile() throws ExtractionException {
  159.         if (!archive.exists()) {
  160.             throw new ExtractionException("Archive file not found: " + archive);
  161.         }
  162.         if (!archive.canRead()) {
  163.             throw new ExtractionException("Can't read archive file: {}" + archive);
  164.         }
  165.     }
  166.  
  167.     private void extractAllArchive(String... files) throws ExtractionException {
  168.         try (RandomAccessFile randomAccessFile = new RandomAccessFile(archive, "r")) {
  169.             extractArchive(randomAccessFile, files);
  170.             LOG.trace("succesfully extracted archive to {}", archive);
  171.         } catch (FileNotFoundException e) {
  172.             throw new ExtractionException("File not found", e);
  173.         } catch (IOException e) {
  174.             throw new ExtractionException("Error closing archive file", e);
  175.         }
  176.     }
  177.  
  178.     private int[] transformFileNamesToIndexes(ISevenZipInArchive inArchive, String... fileNames) throws SevenZipException {
  179.         int[] filesToExtract = null;
  180.         if (fileNames == null || fileNames.length == 0) {
  181.             return filesToExtract;
  182.         }
  183.         int count = inArchive.getNumberOfItems();
  184.         List<Integer> itemsToExtract = new ArrayList<>();
  185.         for (String fileName : fileNames) {
  186.             for (int index = 0; index < count; index++) {
  187.                 if (!((Boolean) inArchive.getProperty(index, PropID.IS_FOLDER)).booleanValue()) {
  188.                     if (fileName.equals(inArchive.getProperty(index, PropID.PATH))) {
  189.                         itemsToExtract.add(index);
  190.                         break;
  191.                     }
  192.                 }
  193.             }
  194.         }
  195.         int index = 0;
  196.         filesToExtract = new int[itemsToExtract.size()];
  197.         for (Integer integer : itemsToExtract) {
  198.             filesToExtract[index++] = integer.intValue();
  199.         }
  200.         return filesToExtract;
  201.     }
  202.  
  203.     private void extractArchive(RandomAccessFile file, String... fileNames) throws ExtractionException {
  204.         ISevenZipInArchive inArchive;
  205.         boolean ok = false;
  206.         int[] filesToExtract;
  207.         try {
  208.             inArchive = SevenZip.openInArchive(null, new RandomAccessFileInStream(file));
  209.             filesToExtract = transformFileNamesToIndexes(inArchive, fileNames);
  210.         } catch (SevenZipException e) {
  211.             throw new ExtractionException("Error opening archive", e);
  212.         }
  213.         try {
  214.             inArchive.extract(filesToExtract, false, new ExtractCallback(inArchive));
  215.             ok = true;
  216.         } catch (SevenZipException e) {
  217.             StringBuilder stringBuilder = new StringBuilder();
  218.             stringBuilder.append("Error extracting archive '");
  219.             stringBuilder.append(archive);
  220.             stringBuilder.append("': ");
  221.             stringBuilder.append(e.getMessage());
  222.             if (e.getCause() != null) {
  223.                 stringBuilder.append(" (");
  224.                 stringBuilder.append(e.getCause().getMessage());
  225.                 stringBuilder.append(')');
  226.             }
  227.             throw new ExtractionException(stringBuilder.toString(), e);
  228.         } finally {
  229.             try {
  230.                 inArchive.close();
  231.             } catch (SevenZipException e) {
  232.                 if (ok) {
  233.                     throw new ExtractionException("Error closing archive", e);
  234.                 }
  235.             }
  236.         }
  237.     }
  238. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement