jar包文件拷贝

  |   0 评论   |   0 浏览

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);
}

}


标题:jar包文件拷贝
作者:llp
地址:https://llinp.cn/articles/2022/06/14/1655182119969.html