Maison  >  Article  >  Java  >  Comment lire les fichiers de ressources dans le package JAR en Java ?

Comment lire les fichiers de ressources dans le package JAR en Java ?

WBOY
WBOYavant
2023-05-08 18:49:098221parcourir

1. Exigences

Dans un projet Java, vous devez lire les fichiers dans le répertoire de ressources, parcourir tous les fichiers du répertoire de ressources spécifié et conserver le chemin relatif du fichier lors de la lecture du fichier.

2. Problème

Lors de l'exécution dans IDEA, vous pouvez obtenir et parcourir les ressources spécifiées, mais après avoir exécuté le projet Java dans un package jar, vous ne pouvez pas obtenir les fichiers dans le répertoire de ressources.

3. IDEA lit les ressources de ressources

Après la compilation, les fichiers de ressources sont placés dans le répertoire cible et chaque fichier de ressources existe réellement sur le disque.

3.1, Méthode 1

Lire directement via le chemin absolu. Si le fichier est un répertoire, vous pouvez également parcourir récursivement les fichiers du répertoire via listFiles :

String absolutePath = "资源文件绝对路径";
File file = new File(absolutePath);
if (file.isDirectory()) {
    File[] children = file.listFiles();
}

3.2, Méthode 2

Lire le chemin relatif :

String path = "template";    //相对resource路径
File file = ResourceUtils.getFile(ResourceUtils.CLASSPATH_URL_PREFIX + path);
if (file.isDirectory()) {
    File[] children = file.listFiles();
}

4, Lisez les ressources après les avoir transformées en package jar

Les deux méthodes ci-dessus ne peuvent pas lire les fichiers de ressources dans le package jar.

Après avoir créé un package jar, le package jar est un fichier distinct plutôt qu'un dossier, de sorte que le fichier de ressources ne peut pas être localisé via le chemin du fichier. À ce stade, les fichiers de ressources du package jar peuvent être lus via le chargeur de classes.

4.1. Lire le fichier de ressources dans le package jar

Cette méthode ne peut lire qu'un seul fichier dans le package jar. Étant donné que ce qui est lu est le flux InputStream, le chemin du fichier relatif à la ressource ne peut pas être conservé, donc. le package jar ne peut pas être lu Parcourez les ressources.

String path = "/resource相对路径";
InputStream is = this.class.getResourceAsStream(path);
byte[] buff = new byte[1024];
String filePath = "保存文件路径";
String fileName = "保存文件名";
File file = new File(filePath + fileName);
FileUtils.copyInputStreamToFile(is, file);

4.2. Parcourez le répertoire des ressources du package jar

En prenant la copie du répertoire des ressources comme exemple, copiez les ressources dans les packages local et jar respectivement.

Comme indiqué ci-dessous :

Je souhaite copier tout le contenu du dossier de modèles dans le répertoire des ressources des ressources ;

Ensuite, enregistrez-le dans le dossier C:/Users/ASUS/Desktop/savePath ;

4.2.1. Jugement environnemental

public static void main(String[] args) throws URISyntaxException {
    // Test为当前类名
    URI uri = Test.class.getProtectionDomain().getCodeSource().getLocation().toURI();
    // tempPath: 文件保存路径
    String tempPath = "C:/Users/ASUS/Desktop/savePath";
    String sourceDir = "template";  //资源文件夹
    if (uri.toString().startsWith("file")) {
        // IDEA运行时,进行资源复制
        copyLocalResourcesFileToTemp(sourceDir + "/", "*", tempPath + "/" + sourceDir);
    } else {
        // 获取jar包所在路径
        String jarPath = uri.toString();
        uri = URI.create(jarPath.substring(jarPath.indexOf("file:"),jarPath.indexOf(".jar") + 4));
        // 打成jar包后,进行资源复制
        Test.copyJarResourcesFileToTemp(uri, tempPath, "BOOT-INF/classes/" + sourceDir);
    }
}

4.2.2 Copiez les fichiers de ressources du projet local

/**
     * 复制本地资源文件到指定目录
     * @param fileRoot      需要复制的资源目录文件夹
     * @param regExpStr     资源文件匹配正则,*表示匹配所有
     * @param tempParent    保存地址
     */
    public static void copyLocalResourcesFileToTemp(String fileRoot, String regExpStr, String tempParent) {
        try {
            ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
            Resource[] resources = resolver.getResources(fileRoot + regExpStr);
            for (Resource resource : resources) {
                File newFile = new File(tempParent, resource.getFilename());
                if (newFile.exists()) {
                    newFile.delete();
                }
                InputStream stream = null;
                try {
                    stream = resource.getInputStream();
                } catch (Exception e) {
                    // 如果resource为文件夹时,会报异常,这里直接忽略这个异常
                }
                if (stream == null) {
                    newFile.mkdirs();
                    copyLocalResourcesFileToTemp(fileRoot + resource.getFilename()  + "/", regExpStr, tempParent + "/" + resource.getFilename());
                } else {
                    if (!newFile.getParentFile().exists()) {
                        newFile.getParentFile().mkdirs();
                    }
                    org.apache.commons.io.FileUtils.copyInputStreamToFile(stream, newFile);
                }
            }
        } catch (Exception e) {
            log.error("failed to copy local source template", e);
        }
    }

4.2.3 Copiez les fichiers de ressources dans le package jar

/**
     * 复制jar包中的资源文件到指定目录
     * @param path          jar包所在路径
     * @param tempPath      保存目录
     * @param filePrefix    需要进行复制的资源文件目录:以BOOT-INF/classes/开头
     */
    public static void copyJarResourcesFileToTemp(URI path, String tempPath, String filePrefix) {
        try {
            List<Map.Entry<ZipEntry, InputStream>> collect =
                    readJarFile(new JarFile(path.getPath()), filePrefix).collect(Collectors.toList());
            for (Map.Entry<ZipEntry, InputStream> entry : collect) {
                // 文件相对路径
                String key = entry.getKey().getName();
                // 文件流
                InputStream stream = entry.getValue();
                File newFile = new File(tempPath + key.replaceAll("BOOT-INF/classes", ""));
                if (!newFile.getParentFile().exists()) {
                    newFile.getParentFile().mkdirs();
                }
                org.apache.commons.io.FileUtils.copyInputStreamToFile(stream, newFile);
            }
        } catch (IOException e) {
            log.error("failed to copy jar source template", e);
        }
    }
@SneakyThrows
    public static Stream<Map.Entry<ZipEntry, InputStream>> readJarFile(JarFile jarFile, String prefix) {
        Stream<Map.Entry<ZipEntry, InputStream>> readingStream =
                jarFile.stream().filter(entry -> !entry.isDirectory() && entry.getName().startsWith(prefix))
                        .map(entry -> {
                            try {
                                return new AbstractMap.SimpleEntry<>(entry, jarFile.getInputStream(entry));
                            } catch (IOException e) {
                                return new AbstractMap.SimpleEntry<>(entry, null);
                            }
                        });
        return readingStream.onClose(() -> {
            try {
                jarFile.close();
            } catch (IOException e) {
                log.error("failed to close jarFile", e);
            }
        });
    }
.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer