Java Tar包的压缩和解压

今日工作中有要求需要对.Tar类型文件进行压缩和解压处理。按照常规处理之后出现了压缩文件乱码,以及压缩文件不能对之进行正常解压的现象。经过一番调整,发现问题在与文件解压与压缩时的编码设置。以下代码基于ant-1.9.2.jar

解压

	/**
	 * 解压tar文件。tar文件中,文件名都是ascii编码,必须中文必须转换为gbk编码。
	 *
	 * @param file
	 * @param outputDir
	 */
	public static void unTar(File file, String outputDir) {
		TarInputStream tarIn = null;
		FileInputStream fileInputStream = null;
		try {
			fileInputStream = new FileInputStream(file);
			tarIn = new TarInputStream(fileInputStream);
			createDirectory(outputDir, null);// 创建输出目录
			TarEntry entry = null;
			while ((entry = tarIn.getNextEntry()) != null && !"".equals(entry.getName())) {
				if (entry.isDirectory()) {// 是目录
					createDirectory(outputDir, entry.getName());// 创建空目录
				} else {// 是文件
					byte[] tmp = new byte[entry.getName().length()];
					for (int i = 0; i < entry.getName().length(); i++) {
						char c = entry.getName().charAt(i);
						byte b = (byte) (0xFF & c);
						tmp[i] = b;
					}
					String fName = new String(tmp, "GBK");
					File tmpFile = new File(outputDir + "/" + fName);

					createDirectory(tmpFile.getParent() + "/", null);// 创建输出目录
					OutputStream out = new FileOutputStream(tmpFile);
					tarIn.copyEntryContents(out);
					closeQuietly(out);
				}
			}
		} catch (Exception e) {
			System.out.println(e.getMessage());
		} finally {
			closeQuietly(fileInputStream);
			closeQuietly(tarIn);
		}
	}

压缩

	/**
	 * 
	 * @param targetFileName
	 * @return
	 */
	private static TarOutputStream getTarOutputStream(String targetFileName) {
		FileOutputStream fileOutputStream = null;
		File path = new File(targetFileName).getParentFile();
		if (!path.exists()) {
			path.mkdirs();
		}
		try {
			fileOutputStream = new FileOutputStream(targetFileName);
		} catch (FileNotFoundException e) {
			System.err.println(e.getMessage());
		}
		BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
		TarOutputStream out = new TarOutputStream(bufferedOutputStream);
		out.setLongFileMode(TarOutputStream.LONGFILE_GNU);// 如果不加下面这段,当压缩包中的路径字节数超过100 byte时,就会报错
		return out;
	}
/**
	 * 
	 * @param inputFile 待打包文件/文件夹
	 * @param targetFileName 
	 */
	public static void pack(File inputFile, String targetFileName) {
		TarOutputStream out = getTarOutputStream(targetFileName);
		tarPack(out, inputFile, inputFile.getName());
		try {
			if (null != out) {
				out.close();
			}
		} catch (IOException e) {
			logger.error(e == null ? "" : e.getMessage(), e);
		}
	}

	/**
	 * 
	 * @param out
	 * @param inputFile  打包后生成文件的流 inputFile
	 * @param base 要压缩的文件夹或文件 base 打包文件中的路径
	 */

	private static void tarPack(TarOutputStream out, File inputFile, String base) {
		if (inputFile.isDirectory()) // 打包文件夹
		{
			packFolder(out, inputFile, base);
		} else // 打包文件
		{
			packFile(out, inputFile, base);
		}
	}

	/**
	 * 
	 * @param out
	 * @param inputFile
	 * @param base
	 */
	private static void packFolder(TarOutputStream out, File inputFile, String base) {
		File[] fileList = inputFile.listFiles();
		try {
			out.putNextEntry(new org.apache.tools.tar.TarEntry(base + "/"));// 在打包文件中添加路径
		} catch (IOException e) {
			System.err.println(e.getMessage());
		}
		base = base.length() == 0 ? "" : base + "/";
		for (File file : fileList) {
			tarPack(out, file, base + file.getName());//回调
		}
	}

	/**
	 * 
	 * @param out
	 * @param inputFile
	 * @param base
	 */
	private static void packFile(TarOutputStream out, File inputFile, String base) {
		TarEntry tarEntry = null;
		try {
			tarEntry = new TarEntry(new String(base.getBytes("GBK"), "ISO-8859-1"));//getBytes必须设置编码,否则会导致编码错误;
		} catch (UnsupportedEncodingException e1) {
			System.err.println(e1.getMessage());
		}
		tarEntry.setSize(inputFile.length());// 设置打包文件的大小,如果不设置,打包有内容的文件时,会报错
		try {
			out.putNextEntry(tarEntry);
		} catch (IOException e) {
			System.err.println(e.getMessage());
		}
		try {
			byte[] wBuf = FileUtils.readFileToByteArray(inputFile);
			out.write(wBuf);
		} catch (IOException e) {
			System.err.println(e.getMessage());
		} catch (NullPointerException e) {
			System.err.println(e.getMessage());
		} finally {
			try {
				if (null != out) {
					out.closeEntry();
				}
			} catch (IOException e) {

			}
		}
	}
Java中,tar文件通常用于压缩和归档目录或文件。如果你想解压一个.tar文件,可以使用一些Java库如Apache Tarball Utility (Taru) 或者是通过Runtime.getRuntime().exec()方法调用操作系统自带的命令行工具。 以下是一个简单的示例,说明如何使用Java的标准工具解压tar文件: ```java import java.io.*; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; public class Main { public static void main(String[] args) { String archivePath = "path_to_your_tar_file.tar"; String destinationDir = "path_to_extract_to"; try { // 创建一个进程运行tar命令 Process proc = Runtime.getRuntime().exec("tar -xvf " + archivePath + " -C " + destinationDir); // 获取进程的输入输出流,用于获取解压过程的日志信息 BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getInputStream())); BufferedReader errorReader = new BufferedReader(new InputStreamReader(proc.getErrorStream())); String line; while ((line = reader.readLine()) != null) { System.out.println(line); } // 检查错误流是否为空,如果非空则表明有错误发生 if ((line = errorReader.readLine()) != null) { System.err.println("Error during extraction: " + line); } // 等待进程结束 int exitCode = proc.waitFor(); if (exitCode != 0) { System.err.println("Command execution failed with exit code: " + exitCode); } } catch (IOException | InterruptedException e) { e.printStackTrace(); } } } ``` 记得替换`archivePath`和`destinationDir`为实际路径。这个例子假设tar文件是标准的tar格式,并且目标目录已经存在。如果需要更复杂的操作,比如处理gzip压缩tar.gz文件,你可以引入额外的库,如`org.apache.commons.compress`。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值