java精简jar包执行过程中用到的包

一,先到自己打包好的jar包目录下执行命令行:java -jar -verbose:class>getClass.txt snake.jar
在这里插入图片描述
在这里插入图片描述

二,分析getClass.txt文件内容
在这里插入图片描述
在这里插入图片描述

三,执行代码如下代码
在这里插入图片描述

四,得到结果
在这里插入图片描述
在这里插入图片描述

五,看到我们已经成功复制了,现在进行打包,执行命令:jar -cvf rt.jar -C rt/ .
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

打包好以后,把jdk中的rt,jar和charsets.jar换成我们自己弄的这个就好,最后贴个代码吧!

JarFileDecompression.java

package cn.simple.jre;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;


public class JarFileDecompression {

	/**
	 * 	解压jar文件到指定目录
	 * @param jarFilePath jar文件的绝对路径,例如:D:/test/rt.jar
	 * @param decompressionJarPath 存放目录的绝对路径,例如:D:/myrt/
	 */
	public JarFileDecompression(String jarFilePath, String decompressionJarPath) {
		JarFile jarFile=null;
		File saveDir = new File(decompressionJarPath);
		if(saveDir.isDirectory()) {
			saveDir.mkdirs();
		}
		
		InputStream is = null;
		FileOutputStream fos = null;
		
		try {
			jarFile = new JarFile(jarFilePath);
			Enumeration<JarEntry> jarItems = jarFile.entries();
			while(jarItems.hasMoreElements()) {
				JarEntry jarItem = jarItems.nextElement();
				//	判断是否是文件夹
				if(!jarItem.isDirectory()) {
					int index = jarItem.getName().lastIndexOf("/");
					String dir ="";
					if(index > 0) {
						dir = jarItem.getName().substring(0, index);						
					}
					new File(decompressionJarPath+dir).mkdirs();
					File newFile = new File(decompressionJarPath+jarItem.getName());
					if(!newFile.exists()) {
						newFile.createNewFile();
					}
					is = jarFile.getInputStream(jarItem);
					fos = new FileOutputStream(newFile);
					byte[] b = new byte[1];
					int len;
					while((len=is.read(b)) != -1) {
						fos.write(b, 0, len);
					}					
				}
				System.out.println("解压文件:"+jarItem.getName()+" 完成!");
			}
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			if(null != fos) {
				try {
					fos.flush();
					fos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(null != is) {
				try {
					is.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(null != jarFile) {
				try {
					jarFile.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		
		
	}

}

GetNeedFile.java

package cn.simple.jre;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class GetNeedFile {
	
	/**
	 *  	得到所需class文件
	 * @param filterClassPath filterClass.txt文件的绝对路径,例如:D:/test/filterClass.txt
	 * @param decompressionJarPath jar文件解压的绝对路径,例如:D:/myjar/
	 * @param copyedFileDir 复制文件存放的绝对路径,例:D:/myrt/
	 */
	public GetNeedFile(String filterClassPath,String decompressionJarPath
			, String copyedFileDir) {
		FileInputStream fis=null;
		BufferedReader br=null;
		try {
			fis = new FileInputStream(filterClassPath);
			br = new BufferedReader(new InputStreamReader(fis));
			
			String textLine;
			String dirName ="";
			
			List<String> allText = new ArrayList<String>();
			while((textLine=br.readLine()) != null) {
				allText.add(textLine);
			}
			
			Iterator<String> getJar = allText.iterator();
			
			//	先将需要的jar文件解压
			while(getJar.hasNext()) {
				textLine = getJar.next();
				if(textLine.endsWith(".jar")) {
					int lastindex=textLine.lastIndexOf(".");
					int firstindex=textLine.lastIndexOf("\\");
					//	获取jar包名,如rt.jar的rt/
					dirName = textLine.substring(firstindex, lastindex)+"/";
					// 	解压jar文件
					new JarFileDecompression(textLine,decompressionJarPath+dirName);
					System.out.println(dirName+"解压完成!");
				}
			}
			
			//	再将需要的class文件复制
			Iterator<String> getClass = allText.iterator();
			
			while(getClass.hasNext()) {
				textLine = getClass.next();
				if(textLine.endsWith(".class")) {
					new CopyFile(decompressionJarPath+textLine
							, copyedFileDir+textLine);
				}
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

FilterFile.java

package cn.simple.jre;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.List;

public class FilterFile {

	/**
	 * getClass.txt文件过滤器,将需要的所有文件全路径写到filterClass.txt文件中
	 * 将getClass.txt文件中的内容进行解析,获取其相关类的绝对路径
	 * 
	 * @param filterFilePath  getClass.txt文件的绝对路径,例如:C:/dir/getClass.txt
	 * @param findSavePath    filterClass.txt存放路径,例如:C:/sava/
	 * @param yourPackagePath 自己包名的前缀,例如我的:cn/snake/
	 *                        当然,也可以只写cn因为jdk中没有cn开头的包,这里只是为了区分自己的包和jdk中的包
	 */
	public FilterFile(String filterFilePath, String findSavePath, String yourPackagePath) {
		// 读取progress.txt内容的流
		FileInputStream fis = null;
		BufferedReader br = null;
		// 写入finaPath.txt内容的流
		try {
			fis = new FileInputStream(filterFilePath);
			br = new BufferedReader(new InputStreamReader(fis));
			String lineText;
			while ((lineText = br.readLine()) != null) {
				// 去除开头的"["和尾部的"]"字符
				lineText = lineText.substring(1, lineText.length() - 1);
				// 第一个空格
				int index_first = lineText.indexOf(' ');
				// 判断开头内容是什么
				if (lineText.startsWith("Opened")) {
					// 获取分开以后的绝对路径
					String jarPath = lineText.substring(index_first + 1, lineText.length());

					// 创建文件
					if (!(new File(findSavePath).exists())) {
						new File(findSavePath).mkdirs();
					}
					File saveFile = new File(findSavePath + "filterClass.txt");
					if (!saveFile.exists()) {
						saveFile.createNewFile();
					}
					writeText(saveFile, jarPath);
				} else if (lineText.startsWith("Loaded")) {
					// 获取第一个空格以后的内容
					String packageAllText = lineText.substring(index_first + 1, lineText.length());

					// 如果不是以.jar结尾的,那不是我们寻找的包
					if (packageAllText.endsWith(".jar")) {
						// 获取其属于哪个jar文件
						int start = packageAllText.lastIndexOf("\\");
						int end = packageAllText.lastIndexOf(".");
						String rootDir = packageAllText.substring(start + 1, end) + "/";

						// 获取第二个空格
						int index_second = packageAllText.indexOf(' ');

						// 获取包名
						String packageText = rootDir + packageAllText.substring(0, index_second);
						// 将包名转换成路径名
						String packageFilePath = packageText.replace('.', '/') + ".class";

						// 排除自己的jar包
						if (!(packageFilePath.startsWith(yourPackagePath))) {
							// 创建保存路径
							if (!(new File(findSavePath).exists())) {
								new File(findSavePath).mkdirs();
							}
							// 创建文件
							File saveFile = new File(findSavePath + "filterClass.txt");
							if (!saveFile.exists()) {
								saveFile.createNewFile();
							}
							// 写内容
							writeText(saveFile, packageFilePath);
						}

					}

				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (null != br) {
				try {
					br.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (null != fis) {
				try {
					fis.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	/**
	 * 将得到的packagePath写入文件
	 * 
	 * @param saveFile        findPath.txt文件
	 * @param packageFilePath 要增加的内容
	 */
	private void writeText(File saveFile, String packageFilePath) {
		FileOutputStream fos = null;
		BufferedWriter bw = null;
		FileInputStream fis = null;
		BufferedReader br = null;
		try {
			fis = new FileInputStream(saveFile);
			br = new BufferedReader(new InputStreamReader(fis));
			// 装原来文件内容的容器
			List<String> oldText = new ArrayList<String>();
			// 读取内容不包括换行符
			String text;
			while ((text = br.readLine()) != null) {
				oldText.add(text);
			}
			br.close();
			fis.close();
			fos = new FileOutputStream(saveFile);
			bw = new BufferedWriter(new OutputStreamWriter(fos));
			if (oldText.isEmpty()) {
				bw.write(packageFilePath + "\n");
			} else {
				for (int i = 0; i < oldText.size(); i++) {
					bw.write(oldText.get(i) + "\n");
				}
				bw.write(packageFilePath + "\n");
			}
			System.out.println("完成文件:" + packageFilePath);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (null != br) {
				try {
					br.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (null != fis) {
				try {
					fis.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (null != bw) {
				try {
					bw.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (null != fos) {
				try {
					fos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

}

CopyFile

package cn.simple.jre;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class CopyFile {
		
	/**
	 * 	复制文件
	 * @param uncopyFile 要复制的文件绝对路径,例如:C:/test/t.txt
	 * @param copyedFilePath 复制文件存放的绝对路径,例如:C:/ss/fds.txt
	 */
	public CopyFile(String uncopyFile,String copyedFilePath) {
		File copyFile = new File(copyedFilePath);
		FileInputStream inFile =null;
		FileOutputStream outFile =null;
		try {
			int index = copyedFilePath.lastIndexOf("/");
			if(index > 0) {				
				String dirPath = copyedFilePath.substring(0, index);
				if(!(new File(dirPath).isDirectory())){
					new File(dirPath).mkdirs();
					if(!copyFile.exists()) {
						copyFile.createNewFile();					
					}
				}
				inFile = new FileInputStream(uncopyFile);
				outFile = new FileOutputStream(copyFile);		
				byte[] b=new byte[1];
				int len;
				while((len=inFile.read(b)) != -1){
					outFile.write(b,0,len);
				}
				System.out.println("复制文件:"+copyedFilePath+" 成功!");
			}
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
			if(null != outFile) {
				try {
					outFile.flush();
					outFile.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(null != inFile) {
				try {
					inFile.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

start.java

package cn.simple.jre;

public class start {
	public static void main(String[] args) {
		//	先过滤掉getClass.txt文件,得到所有需要的filterClass.txt
		new FilterFile("D://MyTest/getClass.txt", "D://MyTest/", "cn/snake/");
		//	再获取
		new GetNeedFile("D://MyTest/filterClass.txt"
				, "D://MyTest/DecomJarFile/", "D://MyTest/NeedAllFile/");
	}
}

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值