原创

Java基础之实现解压和压缩jar、zip、rar等源码分享

有的时候在修改服务器项目中jar包配置时比较费事,相信开发过一定时间的码农们都遇到过类似的问题吧,需要重新打包再上传替换jar包,这样相对比较费事还有可能导致多人修改jar包导致不同步从而系统异常。下面为大家讲述一下如何利用java实现解压并修改解压后的目录中的文件,以及如何重新压缩jar、zip、rar等。

简单封装压缩Compressor.java工具类代码,具体如下:

package com.yoodb.blog;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.zip.CRC32;
import java.util.zip.CheckedOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
 * 压缩工具 
 * @author 路人宅
 */
public class Compressor {
	
	private static Log log = LogFactory.getLog(Compressor.class);
	
	private static final int BUFFER = 8192;

	private File fileName;

	private String originalUrl;

	public Compressor(String pathName) {
		fileName = new File(pathName);
	}

	public void compress(String... pathName) {
		ZipOutputStream out = null;
		try {
			FileOutputStream fileOutputStream = new FileOutputStream(fileName);
			CheckedOutputStream cos = new CheckedOutputStream(fileOutputStream,
					new CRC32());
			out = new ZipOutputStream(cos);
			String basedir = "";
			for (int i = 0; i < pathName.length; i++) {
				compress(new File(pathName[i]), out, basedir);
			}
			out.close();
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	public void compress(String srcPathName) {
		File file = new File(srcPathName);
		if (!file.exists())
			throw new RuntimeException(srcPathName + "不存在!");
		try {
			FileOutputStream fileOutputStream = new FileOutputStream(fileName);
			CheckedOutputStream cos = new CheckedOutputStream(fileOutputStream,
					new CRC32());
			ZipOutputStream out = new ZipOutputStream(cos);
			String basedir = "";
			compress(file, out, basedir);
			out.close();
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	private void compress(File file, ZipOutputStream out, String basedir) {
		/* 判断是目录还是文件 */
		if (file.isDirectory()) {
			this.compressDirectory(file, out, basedir);
		} else {
			this.compressFile(file, out, basedir);
		}
	}

	/**
	 *  压缩目录
	 * @param dir
	 * @param out
	 * @param basedir
	 */
	private void compressDirectory(File dir, ZipOutputStream out, String basedir) {
		if (!dir.exists())
			return;

		File[] files = dir.listFiles();
		for (int i = 0; i < files.length; i++) {
			/* 递归 */
			compress(files[i], out, basedir + dir.getName() + "/");
		}
	}

	/**
	 * 压缩文件 
	 * @param file
	 * @param out
	 * @param basedir
	 */
	private void compressFile(File file, ZipOutputStream out, String basedir) {
		if (!file.exists()) {
			return;
		}
		try {
			BufferedInputStream bis = new BufferedInputStream(
					new FileInputStream(file));
			String filePath = (basedir + file.getName())
			    .replaceAll(getOriginalUrl() + "/", "");
			log.info("压缩文件:" + filePath);
			ZipEntry entry = new ZipEntry(filePath);
			out.putNextEntry(entry);
			int count;
			byte data[] = new byte[BUFFER];
			while ((count = bis.read(data, 0, BUFFER)) != -1) {
				out.write(data, 0, count);
			}
			bis.close();
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	public static void main(String[] args) {
		Compressor zc = new Compressor("E:\\org.wso2.carbon.service.mgt.ui_4.7.1.jar");
		zc.compress("E:\\org.wso2.carbon.service.mgt.ui_4.7.0");
	}

	public String getOriginalUrl() {
		return originalUrl;
	}

	public void setOriginalUrl(String originalUrl) {
		this.originalUrl = originalUrl;
	}

}

分析:

新建对象并传入新压缩包路径参数,调用compress方法传入需要压缩的目录路径,创建File对象传入参数,判断是否存在,不存在抛出异常,之后进行一系列创建或判断操作后,压缩目录创建压缩包。

简单封装解压Decompression.java工具类代码,具体如下:

package com.yoodb.blog;
import java.io.File;  
import java.io.FileOutputStream;  
import java.io.IOException;  
import java.io.InputStream;  
import java.nio.ByteBuffer;  
import java.nio.channels.Channels;  
import java.nio.channels.FileChannel;  
import java.nio.channels.ReadableByteChannel;  
import java.util.Enumeration;  
import java.util.jar.JarEntry;  
import java.util.jar.JarFile;  

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
  
/**
 * 解压工具 
 * @author 路人宅
 */
public class Decompression {  
	
	protected static Log log = LogFactory.getLog(Decompression.class);
  
    @SuppressWarnings("resource")
	public static void uncompress(File jarFile, File tarDir) throws IOException {  
JarFile jfInst = new JarFile(jarFile);  
Enumeration enumEntry = jfInst.entries();  
while (enumEntry.hasMoreElements()) {  
    JarEntry jarEntry = enumEntry.nextElement();  
    File tarFile = new File(tarDir, jarEntry.getName());  
    if(jarEntry.getName().contains("META-INF")){
    	File miFile = new File(tarDir, "META-INF"); 
    	if(!miFile.exists()){
    		miFile.mkdirs();
    	}
    	
	}
    makeFile(jarEntry, tarFile);  
    if (jarEntry.isDirectory()) {  
continue;  
    }  
    FileChannel fileChannel = new FileOutputStream(tarFile).getChannel();  
    InputStream ins = jfInst.getInputStream(jarEntry);  
    transferStream(ins, fileChannel);  
}  
    }  
  
    /** 
     * 流交换操作
     * @param ins 输入流 
     * @param channel 输出流 
     */  
    private static void transferStream(InputStream ins, FileChannel channel) {  
ByteBuffer byteBuffer = ByteBuffer.allocate(1024 * 10);  
ReadableByteChannel rbcInst = Channels.newChannel(ins);  
try {  
    while (-1 != (rbcInst.read(byteBuffer))) {  
byteBuffer.flip();  
channel.write(byteBuffer);  
byteBuffer.clear();  
    }  
} catch (IOException ioe) {  
    ioe.printStackTrace();  
} finally {  
    if (null != rbcInst) {  
try {  
    rbcInst.close();  
} catch (IOException e) {  
    e.printStackTrace();  
}  
    }  
    if (null != channel) {  
try {  
    channel.close();  
} catch (IOException e) {  
    e.printStackTrace();  
}  
    }  
}  
    }  
  
    /** 
     * 打印jar文件内容信息 
     * @param file jar文件 
     */  
    public static void printJarEntry(File file) {  
JarFile jfInst = null;;  
try {  
    jfInst = new JarFile(file);  
} catch (IOException e) {  
    e.printStackTrace();  
}  
Enumeration enumEntry = jfInst.entries();  
while (enumEntry.hasMoreElements()) {  
	log.info((enumEntry.nextElement()));  
}  
    }  
  
    /** 
     * 创建文件 
     * @param jarEntry jar实体 
     * @param fileInst 文件实体 
     * @throws IOException 抛出异常 
     */  
    public static void makeFile(JarEntry jarEntry, File fileInst) {  
if (!fileInst.exists()) {  
    if (jarEntry.isDirectory()) {  
fileInst.mkdirs();  
    } else {  
try {  
    fileInst.createNewFile();
} catch (IOException e) { 
	log.error("创建文件失败>>>".concat(fileInst.getPath()));  
}  
    }  
}  
    }  
    
    public static void main(String[] args) {  
File jarFile = new File("E:\\org.wso2.carbon.service.mgt.ui_4.7.0.jar");  
File targetDir = new File("E:\\org.wso2.carbon.service.mgt.ui_4.7.0"); 
try {  
    Decompression.uncompress(jarFile, targetDir);  
} catch (IOException e) {  
    e.printStackTrace();  
}  
    }  
}

分析:

新建两个File对象分别是压缩包路径和需要解压到的指定目录路径,之后调用uncompress方法进行一些创建、修改以及判断操作,解压成功。

利用上述两个Decompression.java 和Compressor.java工具类,进行解压重新打包操作,有什么疑难问题欢迎大家留言咨询,每日持续更新技术文章,感兴趣欢迎收藏。

~阅读全文~人机检测~

关注下方微信公众号“Java精选”(w_z90110),回复关键词领取资料:如Mysql、Hadoop、Dubbo、Spring Boot等,免费领取视频教程、资料文档和项目源码。

Java精选专注程序员推送一些Java开发知识,包括基础知识、各大流行框架(Mybatis、Spring、Spring Boot等)、大数据技术(Storm、Hadoop、MapReduce、Spark等)、数据库(Mysql、Oracle、NoSQL等)、算法与数据结构、面试专题、面试技巧经验、职业规划以及优质开源项目等。其中一部分由小编总结整理,另一部分来源于网络上优质资源,希望对大家的学习和工作有所帮助。

评论

  1. #1

    (2019/09/10 23:57:57)回复
    快乐生活20189 1 分钟前 JAVA 实现最新的winrar 5 压缩格式的解压。参考 https://blog.csdn.net/liaowufeng2012/article/details/100697195

分享:

支付宝

微信