Package ef.impl.archive

Source Code of ef.impl.archive.Archiver

package ef.impl.archive;

import org.apache.commons.compress.archivers.ArchiveEntry;
import org.apache.commons.compress.archivers.ArchiveInputStream;
import org.apache.commons.compress.archivers.ArchiveOutputStream;
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
import org.apache.commons.io.IOUtils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Collection;
import java.util.Deque;
import java.util.LinkedList;

/**
* User: sduchenko
* Date: 23.04.13
* Time: 18:45
*/
public class Archiver {

    public static void createArchive(ArchiveType archiveType, Collection<File> files, File archiveFile) throws IOException {
        ArchiveOutputStream aos;
        switch (archiveType){
            case TAR:
                aos = new TarArchiveOutputStream(new FileOutputStream(archiveFile), "UTF-8");
                ((TarArchiveOutputStream)aos).setLongFileMode(TarArchiveOutputStream.LONGFILE_POSIX);
                break;
            case ZIP: aos = new ZipArchiveOutputStream(new FileOutputStream(archiveFile)); break;
            default:
                throw new IOException("archive type not supported");
        }

        Deque<Entry> stack = new LinkedList<Entry>();
        putEntries(stack, null, files);

        int entriesToClose = 0;
        boolean wasError = false;
        try {
            while(!stack.isEmpty()){
                Entry e = stack.pop();

                ArchiveEntry entry = aos.createArchiveEntry(e.file, e.baseName);
                aos.putArchiveEntry(entry);
                entriesToClose++;
                if(e.file.isDirectory()){
                    File[] list = e.file.listFiles();
                    if(list != null && list.length > 0){
                        putEntries(stack, e.baseName, list);
                    }
                }else{
                    FileInputStream fis = new FileInputStream(e.file);
                    try {
                        IOUtils.copy(fis, aos);
                    } finally {
                        fis.close();
                    }
                }
                aos.closeArchiveEntry();
                entriesToClose--;
            }
        } catch(Exception e){
            wasError = true;

            while(entriesToClose-- >0){
                try {
                    aos.closeArchiveEntry();
                } catch (IOException ignored) {}
            }

            if(e instanceof IOException){
                throw (IOException) e;
            }

            throw new IOException(e);
        } finally {
            try {
                aos.close();
            } catch (IOException ignore) {}

            if(wasError){
                archiveFile.delete();
            }
        }
    }

    public static void extractArchive(ArchiveType archiveType, File srcFile, File dstDir) throws IOException {
        ArchiveInputStream ais;
        switch (archiveType){
            case TAR:
                    ais = new TarArchiveInputStream(new FileInputStream(srcFile));
                break;
            case ZIP:
                    ais = new ZipArchiveInputStream(new FileInputStream(srcFile));
                break;
            default:
                throw new IOException("archive type not supported");
        }

        ArchiveEntry entry;
        try {
            while((entry = ais.getNextEntry()) != null){
                File file = new File(dstDir, entry.getName());

                if(entry.isDirectory()){
                    if(!file.mkdirs()){
                        throw new IOException("unable to create directory tree: "+file.getPath());
                    }
                    continue;
                }

                FileOutputStream fos = new FileOutputStream(file);
                try {
                    IOUtils.copy(ais, fos);
                } finally {
                    try {
                        fos.close();
                    } catch (IOException ignored) {}
                }
            }
        } finally {
            try {
                ais.close();
            } catch (IOException ignored) {}
        }
    }

    private static void putEntries(Deque<Entry> stack, String baseName, Collection<File> files){
        baseName = baseName == null ? "" : baseName + "/";
        for(File file: files){
            stack.push(new Entry(baseName + file.getName(), file));
        }
    }

    private static void putEntries(Deque<Entry> stack, String baseName, File[] files){
        baseName = baseName == null ? "" : baseName + "/";
        for(File file: files){
            stack.push(new Entry(baseName + file.getName(), file));
        }
    }

    private static class Entry {
        String baseName;
        File file;

        Entry(String baseName, File file) {
            this.baseName = baseName;
            this.file = file;
        }
    }
}
TOP

Related Classes of ef.impl.archive.Archiver

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.