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) {

			}
		}
	}

你可能感兴趣的:(Tar)