jar包文件拷贝
public class FileUtil {
private static Logger log = LoggerFactory.getLogger(FileUtil.class);
/**
* 从jar包中获取文件
*
* @param folderPath 源文件目录 /CPCN
* @param targetFolderPath 目标目录 /usr/local/software/jdk/
* @param clazz Class对象 ZJWebappListener.class
* @throws IOException
*/
public static void loadRecourseFromJarByFolder(String folderPath, String targetFolderPath, Class clazz) {
//根据源文件目录获取url ==>ZJWebappListener.class.getResource("/CPCN");
URL url = clazz.getResource(folderPath);
try {
//获取连接
URLConnection urlConnection = url.openConnection();
//判断是读取普通的文件还是jar包中的文件
if (urlConnection instanceof FileURLConnection) {
//拷贝当前运行环境资源文件是在文件里面的文件
copyFileResources(url, folderPath, targetFolderPath, clazz);
} else if (urlConnection instanceof JarURLConnection) {
//拷贝当前运行环境资源文件是在jar里面的文件
copyJarResources((JarURLConnection) urlConnection, targetFolderPath, clazz);
}
} catch (IOException e) {
e.printStackTrace();
log.error(ExceptionUtils.getStackTrace(e));
}
}
/**
* 当前运行环境资源文件是在文件里面的
*
* @param url
* @param folderPath
* @param targetFolderPath
* @param clazz
*/
private static void copyFileResources(URL url, String folderPath, String targetFolderPath, Class clazz) {
File root = new File(url.getPath());
if (root.isDirectory()) {
File[] files = root.listFiles();
for (File file : files) {
if (file.isDirectory()) {
loadRecourseFromJarByFolder(folderPath + "/" + file.getName(), targetFolderPath, clazz);
} else {
try {
loadRecourseFromJar(folderPath + "/" + file.getName(), targetFolderPath, clazz);
} catch (IOException e) {
e.printStackTrace();
log.error(ExceptionUtils.getStackTrace(e));
}
}
}
}
}
/**
* JarURLConnection 实例只能用于从 JAR 文件中读取。无法使用此类获取java.io.OutputStream来修改或写入底层 JAR 文件。
* 例子:
* 一个 Jar 条目
* jar:http://www.foo.com/bar/baz.jar!/COM/foo/Quux.class
* 一个 Jar 文件
* jar:http://www.foo.com/bar/baz.jar!/
* 一个 Jar 目录
* jar:http://www.foo.com/bar/baz.jar!/COM/foo/
*
* @param jarURLConnection
* @param targetFolderPath /usr/local/software/jdk/
* @param clazz
* @throws IOException
*/
private static void copyJarResources(JarURLConnection jarURLConnection, String targetFolderPath, Class clazz) throws IOException {
//根据连接获取JAR文件
JarFile jarFile = jarURLConnection.getJarFile();
//获取jar包中的所有文件
// /usr/local/software/jdk/app.jar!/BOOT-INF/classes!/CPCN
Enumeration<JarEntry> entrys = jarFile.entries();
while (entrys.hasMoreElements()) {
JarEntry entry = entrys.nextElement();
//获取目录名称 CPCN
if (entry.getName().startsWith(jarURLConnection.getEntryName()) && !entry.getName().endsWith("/")) {
loadRecourseFromJar("/" + entry.getName(), targetFolderPath, clazz);
}
}
jarFile.close();
}
/**
* @param path /CPCN
* @param recourseFolder /usr/local/software/jdk/
* @param clazz ZJWebappListener.class
* @throws IOException
*/
private static void loadRecourseFromJar(String path, String recourseFolder, Class clazz) throws IOException {
if (!path.startsWith("/")) {
throw new IllegalArgumentException("路径必须是以 '/' 开头.");
}
if (path.endsWith("/")) {
throw new IllegalArgumentException("路径不能不以 '/' 结尾.");
}
int index = path.lastIndexOf('/');
// CPCN
String filename = path.substring(index + 1);
// /usr/local/software/jdk/CPCN
String folderPath = recourseFolder + path.substring(0, index + 1);
/**
* 如果该文件夹尚不存在,则会创建该文件夹。
* 如果文件夹存在则忽略
*/
File dir = new File(folderPath);
if (!dir.exists()) {
//创建多级目录
dir.mkdirs();
}
/**
* 如果该文件尚不存在,则会创建该文件。
* 如果文件存在则忽略
*/
filename = folderPath + filename;
File file = new File(filename);
if (!file.exists() && !file.createNewFile()) {
log.error("创建文件失败,文件名:" + filename);
return;
}
byte[] buffer = new byte[1024];
int readBytes;
//获取连接
URL url = clazz.getResource(path);
URLConnection urlConnection = url.openConnection();
InputStream is = urlConnection.getInputStream();
if (is == null) {
throw new FileNotFoundException("文件 " + path + ",在jar包中没有找到.");
}
OutputStream os = new FileOutputStream(file);
try {
while ((readBytes = is.read(buffer)) != -1) {
//读多少写多少
os.write(buffer, 0, readBytes);
}
} finally {
if (os != null) {
os.close();
}
if (is != null) {
is.close();
}
}
}
public static void main(String[] args) throws IOException {
loadRecourseFromJarByFolder("/lua", "E:\\test", FileUtil.class);
}
}