All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.wicp.tams.common.apiext.TarUtil Maven / Gradle / Ivy

There is a newer version: 6.1.0
Show newest version
/*
 * Copyright 2015 Zhongan.com All right reserved. This software is the
 * confidential and proprietary information of Zhongan.com ("Confidential
 * Information"). You shall not disclose such Confidential Information and shall
 * use it only in accordance with the terms of the license agreement you entered
 * into with Zhongan.com.
 */
package net.wicp.tams.common.apiext;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
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 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.compressors.gzip.GzipCompressorInputStream;
import org.apache.commons.compress.utils.IOUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.ArrayUtils;

import lombok.extern.slf4j.Slf4j;
import net.wicp.tams.common.exception.ExceptAll;
import net.wicp.tams.common.exception.ProjectExceptionRuntime;

/****
 * 
 * @author zhoujunhui
 *
 */
@Slf4j
public class TarUtil {

	/***
	 * 解压tar文件
	 * 
	 * @param tarFilePath tar的路径
	 * @param directory   解压后的存放路径
	 * @param needLastDir 是否需要进一步,ture:解压后只有一个文件,会把这个文件夹返回出去,false:即使只有一个文件夹也不会返回最后一个文件夹,只会返回directory
	 * @return 最后解压后的文件路径,默认为directory,如果needLastDir=true且解压后只有一个文件 夹时则会返回这个文件夹地址
	 */
	public static String decompress(String tarFilePath, String directory, boolean needLastDir) {
		String retDir = directory;
		File tarFile = new File(tarFilePath);
		if (!tarFile.exists()) {
			throw new RuntimeException("tar file is not exists.");
		}

		if (!tarFile.isFile()) {
			throw new RuntimeException("compress file is not a file.");
		}
		try {
			InputStream ins = new FileInputStream(tarFile);
			decompress(ins, directory);
			String[] list = new File(directory).list();
			if (needLastDir && ArrayUtils.isNotEmpty(list) && list.length == 1) {
				retDir = IOUtil.mergeFolderAndFilePath(directory, list[0]);
			}
			return retDir;
		} catch (FileNotFoundException e) {
			log.error("没有这个文件:{}", tarFilePath);
			throw new RuntimeException("tar file is not exists.", e);
		}
	}

	public static String decompress(String tarFilePath, String directory) {
		return decompress(tarFilePath, directory, true);
	}

	/***
	 * 解压tar到当前目录下
	 * 
	 * @param tarFilePath tar文件的路径
	 */
	public static String decompress(String tarFilePath, boolean needLastDir) {
		tarFilePath = tarFilePath.replace("\\", "/");
		int index = tarFilePath.lastIndexOf("/");
		String retpath = decompress(tarFilePath, tarFilePath.substring(0, index), needLastDir);
		return retpath;
	}

	public static void decompress(InputStream is, String directory) {
		TarArchiveInputStream in = null;
		try {
			in = new TarArchiveInputStream(is, "utf-8");
			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 = null;
				try {
					out = new FileOutputStream(curfile);
					IOUtils.copy(in, out);
					entry = in.getNextTarEntry();
				} finally {
					out.close();
				}
			}
			in.close();

		} catch (Exception e) {
			log.error("compress tar error.", e);
		} finally {
			if (in != null) {
				try {
					in.close();
				} catch (IOException e) {
					log.error("compress tar error.", e);
				}
			}
			if (is != null) {
				try {
					is.close();
				} catch (IOException e) {
					log.error("compress tar error.", e);
				}
			}
		}
	}

	public static void decompress(byte[] bytes, String directory) {
		ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
		decompress(bais, directory);
	}

	public static String deCompressTGZFile(String filePath) {
		return deCompressTGZFile(new File(filePath), true);
	}

	public static String deCompressTGZFile(File file) {
		return deCompressTGZFile(file, true);
	}

	public static String deCompressTGZFile(File file, boolean needLastDir) {
		File tgzToTar = tgzToTar(file);
		String tempdir = tgzToTar.getPath().replace(".tar", "");
		String retpath = decompress(tgzToTar.getPath(), tempdir, needLastDir);
		try {
			FileUtils.forceDelete(tgzToTar);
		} catch (Exception e) {
		}
		return retpath;
	}

	// 把tgz文件解压为tar文件
	private static File tgzToTar(File file) {
		if(file.isDirectory()||!file.getName().endsWith(".tgz")) {
			throw new ProjectExceptionRuntime(ExceptAll.param_error,"解压的文件需要以.tgz结尾,却传来文件:"+file.getPath());
		}
		FileOutputStream out = null;
		GzipCompressorInputStream gzIn = null;
		int buffersize = 2048;
		try {
			FileInputStream fin = new FileInputStream(file);
			BufferedInputStream in = new BufferedInputStream(fin);
			String tarname = file.getName().replace(".tgz", ".tar");
			File outFile = new File(file.getParent() + File.separator + tarname);
			out = new FileOutputStream(outFile);
			gzIn = new GzipCompressorInputStream(in);
			final byte[] buffer = new byte[buffersize];
			int n = 0;
			while (-1 != (n = gzIn.read(buffer))) {
				out.write(buffer, 0, n);
			}
			return outFile;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		} finally {
			try {
				out.close();
				gzIn.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	/////////////////////////////////////////////////////////////////////////////////// 来自网络//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	private static final String TAG = TarUtil.class.getName();
	private static final int BUFFER = 1024;
	private static String mCompressSrcParentPath = "";

	/**
	 * usage: compress("/mnt/sdcard/Download", "/mnt/sdcard/Download.tar");
	 * 
	 * @param srcAbsolutePath  can be path of file or directory
	 * @param destAbsolutePath suggest ending with a ".tar" suffix
	 */
	public static void compress(String srcAbsolutePath, String destAbsolutePath) {
		compress(new File(srcAbsolutePath), destAbsolutePath);
	}

	/**
	 * @param srcFile          can be file or directory
	 * @param destAbsolutePath suggest ending with a ".tar" suffix
	 */
	public static void compress(File srcFile, String destAbsolutePath) {
		File destFile = new File(destAbsolutePath);
		try {
			if (!destFile.exists()) {
				destFile.createNewFile();
			}
			TarArchiveOutputStream taos = new TarArchiveOutputStream(new FileOutputStream(destFile));
			mCompressSrcParentPath = srcFile.getParent() + File.separator;
			compress(srcFile, taos);
			taos.flush();
			taos.close();
		} catch (IOException e) {
			log.info(TAG, e.toString());
		}
	}

	private static void compress(File file, TarArchiveOutputStream taos) {
		if (file.isDirectory()) {
			compressDir(file, taos);
		} else {
			compressFile(file, taos);
		}
	}

	private static void compressDir(File dir, TarArchiveOutputStream taos) {
		File[] files = dir.listFiles();
		if (files != null) {
			if (files.length == 0) {
				try {
					taos.putArchiveEntry(createTarArchiveEntry(dir));
					taos.closeArchiveEntry();
				} catch (IOException e) {
					log.info(TAG, e.toString());
				}
			} else {
				for (File file : files) {
					compress(file, taos);
				}
			}
		}
	}

	private static TarArchiveEntry createTarArchiveEntry(File file) {
		/**
		 * 不能用绝对路径,举例对于压缩/mnt/sdcard下的abc文件,如果不做截短,压缩文件里面会在abc外面套mnt和sdcard两层空壳,所以要把abc所属路径的/mnt/sdcard去掉
		 **/
		return new TarArchiveEntry(file, file.getPath().replace(mCompressSrcParentPath, ""));
	}

	private static void compressFile(File file, TarArchiveOutputStream taos) {
		try {
			BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
			taos.putArchiveEntry(createTarArchiveEntry(file));
			int count;
			byte data[] = new byte[BUFFER];
			while ((count = bis.read(data, 0, BUFFER)) != -1) {
				taos.write(data, 0, count);
			}
			bis.close();
			taos.closeArchiveEntry();
		} catch (IOException e) {
			log.info(TAG, e.toString());
		}
	}

	// usage: extract("/mnt/sdcard/Download.tar", "/mnt/sdcard")
	public static void extract(String srcPath, String destPath) {
		File srcFile = new File(srcPath);
		if (srcFile.isFile()) {
			extract(srcFile, destPath);
		}
	}

	public static void extract(File srcFile, String destPath) {
		extract(srcFile, new File(destPath));
	}

	public static void extract(File srcFile, File destFile) {
		try {
			TarArchiveInputStream tais = new TarArchiveInputStream(new FileInputStream(srcFile));
			extract(destFile, tais);
			tais.close();
		} catch (IOException e) {
			log.info(TAG, e.toString());
		}
	}

	private static void extract(File destFile, TarArchiveInputStream tais) {
		TarArchiveEntry entry = null;
		try {
			while ((entry = tais.getNextTarEntry()) != null) {
				String dirPath = destFile.getPath() + File.separator + entry.getName();
				File dirFile = new File(dirPath);
				createParentDirRecursively(dirFile);
				if (entry.isDirectory()) {
					dirFile.mkdirs();
				} else {
					extractFile(dirFile, tais);
				}
			}
		} catch (IOException e) {
			log.info(TAG, e.toString());
		}
	}

	private static void extractFile(File destFile, TarArchiveInputStream tais) {
		BufferedOutputStream bos;
		try {
			bos = new BufferedOutputStream(new FileOutputStream(destFile));
			int count;
			byte data[] = new byte[BUFFER];
			while ((count = tais.read(data, 0, BUFFER)) != -1) {
				bos.write(data, 0, count);
			}
			bos.close();
		} catch (FileNotFoundException e) {
			log.info(TAG, e.toString());
		} catch (IOException e) {
			log.info(TAG, e.toString());
		}
	}

	private static void createParentDirRecursively(File dirFile) {
		File parentFile = dirFile.getParentFile();
		if (!parentFile.exists()) {
			createParentDirRecursively(parentFile);
			parentFile.mkdir();
		}
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy