org.waarp.common.tar.TarUtility.java Source code

Java tutorial

Introduction

Here is the source code for org.waarp.common.tar.TarUtility.java

Source

/**
 * This file is part of Waarp Project.
 * 
 * Copyright 2009, Frederic Bregier, and individual contributors by the @author tags. See the
 * COPYRIGHT.txt in the distribution for a full listing of individual contributors.
 * 
 * All Waarp Project is free software: you can redistribute it and/or modify it under the terms of
 * the GNU General Public License as published by the Free Software Foundation, either version 3 of
 * the License, or (at your option) any later version.
 * 
 * Waarp is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
 * Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along with Waarp . If not, see
 * <http://www.gnu.org/licenses/>.
 */
package org.waarp.common.tar;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
import org.apache.commons.compress.utils.IOUtils;

/**
 * TAR support
 * 
 * @author Frederic Bregier
 * 
 */
public class TarUtility {
    /**
     * Create a new Tar from a root directory
     * 
     * @param directory
     *            the base directory
     * @param filename
     *            the output filename
     * @param absolute
     *            store absolute filepath (from directory) or only filename
     * @return True if OK
     */
    public static boolean createTarFromDirectory(String directory, String filename, boolean absolute) {
        File rootDir = new File(directory);
        File saveFile = new File(filename);
        // recursive call
        TarArchiveOutputStream taos;
        try {
            taos = new TarArchiveOutputStream(new FileOutputStream(saveFile));
        } catch (FileNotFoundException e) {
            return false;
        }
        taos.setLongFileMode(TarArchiveOutputStream.LONGFILE_GNU);
        try {
            recurseFiles(rootDir, rootDir, taos, absolute);
        } catch (IOException e2) {
            try {
                taos.close();
            } catch (IOException e) {
                // ignore
            }
            return false;
        }
        try {
            taos.finish();
        } catch (IOException e1) {
            // ignore
        }
        try {
            taos.flush();
        } catch (IOException e) {
            // ignore
        }
        try {
            taos.close();
        } catch (IOException e) {
            // ignore
        }
        return true;
    }

    /**
     * Recursive traversal to add files
     * 
     * @param root
     * @param file
     * @param taos
     * @param absolute
     * @throws IOException
     */
    private static void recurseFiles(File root, File file, TarArchiveOutputStream taos, boolean absolute)
            throws IOException {
        if (file.isDirectory()) {
            // recursive call
            File[] files = file.listFiles();
            for (File file2 : files) {
                recurseFiles(root, file2, taos, absolute);
            }
        } else if ((!file.getName().endsWith(".tar")) && (!file.getName().endsWith(".TAR"))) {
            String filename = null;
            if (absolute) {
                filename = file.getAbsolutePath().substring(root.getAbsolutePath().length());
            } else {
                filename = file.getName();
            }
            TarArchiveEntry tae = new TarArchiveEntry(filename);
            tae.setSize(file.length());
            taos.putArchiveEntry(tae);
            FileInputStream fis = new FileInputStream(file);
            IOUtils.copy(fis, taos);
            taos.closeArchiveEntry();
        }
    }

    /**
     * Create a new Tar from a list of Files (only name of files will be used)
     * 
     * @param files
     *            list of files to add
     * @param filename
     *            the output filename
     * @return True if OK
     */
    public static boolean createTarFromFiles(List<File> files, String filename) {
        return createTarFromFiles(files.toArray(new File[] {}), filename);
    }

    /**
     * Create a new Tar from an array of Files (only name of files will be used)
     * 
     * @param files
     *            array of files to add
     * @param filename
     *            the output filename
     * @return True if OK
     */
    public static boolean createTarFromFiles(File[] files, String filename) {
        File saveFile = new File(filename);
        // recursive call
        TarArchiveOutputStream taos;
        try {
            taos = new TarArchiveOutputStream(new FileOutputStream(saveFile));
        } catch (FileNotFoundException e) {
            return false;
        }
        taos.setLongFileMode(TarArchiveOutputStream.LONGFILE_GNU);
        for (File file : files) {
            try {
                addFile(file, taos);
            } catch (IOException e) {
                try {
                    taos.close();
                } catch (IOException e1) {
                    // ignore
                }
                return false;
            }
        }
        try {
            taos.finish();
        } catch (IOException e1) {
            // ignore
        }
        try {
            taos.flush();
        } catch (IOException e) {
            // ignore
        }
        try {
            taos.close();
        } catch (IOException e) {
            // ignore
        }
        return true;
    }

    /**
     * Recursive traversal to add files
     * 
     * @param file
     * @param taos
     * @throws IOException
     */
    private static void addFile(File file, TarArchiveOutputStream taos) throws IOException {
        String filename = null;
        filename = file.getName();
        TarArchiveEntry tae = new TarArchiveEntry(filename);
        tae.setSize(file.length());
        taos.putArchiveEntry(tae);
        FileInputStream fis = new FileInputStream(file);
        IOUtils.copy(fis, taos);
        taos.closeArchiveEntry();
    }

    /**
     * Extract all files from Tar into the specified directory
     * 
     * @param tarFile
     * @param directory
     * @return the list of extracted filenames
     * @throws IOException
     */
    public static List<String> unTar(File tarFile, File directory) throws IOException {
        List<String> result = new ArrayList<String>();
        InputStream inputStream = new FileInputStream(tarFile);
        TarArchiveInputStream in = new TarArchiveInputStream(inputStream);
        TarArchiveEntry entry = in.getNextTarEntry();
        while (entry != null) {
            if (entry.isDirectory()) {
                entry = in.getNextTarEntry();
                continue;
            }
            File curfile = new File(directory, entry.getName());
            File parent = curfile.getParentFile();
            if (!parent.exists()) {
                parent.mkdirs();
            }
            OutputStream out = new FileOutputStream(curfile);
            IOUtils.copy(in, out);
            out.close();
            result.add(entry.getName());
            entry = in.getNextTarEntry();
        }
        in.close();
        return result;
    }

    public static void main(String[] args) {
        if (args.length < 3) {
            System.err.println("You need to provide 3 arguments:\n" + "   option filedest.tar \"source\"\n"
                    + "   where option=1 means untar and source is a directory\n"
                    + "   option=2 means tar and source is a directory\n"
                    + "   option=3 means tar and source is a list of files comma separated");
            System.exit(1);
        }
        int option = Integer.parseInt(args[0]);
        String tarfile = args[1];
        String tarsource = args[2];
        String[] tarfiles = null;
        if (option == 3) {
            tarfiles = args[2].split(",");
            File[] files = new File[tarfiles.length];
            for (int i = 0; i < tarfiles.length; i++) {
                files[i] = new File(tarfiles[i]);
            }
            if (createTarFromFiles(files, tarfile)) {
                System.out.println("TAR OK from multiple files");
            } else {
                System.err.println("TAR KO from multiple files");
            }
        } else if (option == 2) {
            if (createTarFromDirectory(tarsource, tarfile, false)) {
                System.out.println("TAR OK from directory");
            } else {
                System.err.println("TAR KO from directory");
            }
        } else if (option == 1) {
            File tarFile = new File(tarfile);
            File directory = new File(tarsource);
            List<String> result = null;
            try {
                result = unTar(tarFile, directory);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            if (result == null || result.isEmpty()) {
                System.err.println("UNTAR KO from directory");
            } else {
                for (String string : result) {
                    System.out.println("File: " + string);
                }
            }
        }

    }
}