如何读取jar包中的文件

1.getResource

//当前类文件为根目录,取其子目录x下的y文件
Main.class.getResource("x/y")

//当前类文件的根目录为根目录,取其子目录x下的y文件
Main.class.getResource("/x/y")

上面的解释有点拗口,其实就是路径不以斜线开头,表示从当前class文件为根目录,然后找文件,路径以斜线开头,则从当前class的文件的根目录,比如当前class如果有包限定的话,那就是从包的最顶层,作为根目录,来加载文件。

2.getResourceAsStream

 

private static String readFile(String file) throws IOException {
        InputStream input = null;
        BufferedInputStream bis = null;
        StringBuilder sb = new StringBuilder();
        try {
            input = Main.class.getResourceAsStream(file);
            bis = new BufferedInputStream(input);

            byte[] temp = new byte[1024];
            int len;
            while ((len = bis.read(temp)) != -1) {
                sb.append(new String(temp, 0, len, StandardCharsets.UTF_8));
            }
        } finally {
            if (bis != null) {
                bis.close();
            }

            if (input != null) {
                input.close();
            }
        }

        return sb.toString();
    }

 这里要注意的是,上面的写法中是Main.class.getResourceAsStream(file),即从当前类的范围内去找file,

如果写成Main.class.getClassLoader().getResourceAsStream(file),则有可能找不到文件,因为已经从加载器的可见范围去找文件了。

 

3.JarFile

private static String readFile(String file) throws IOException {
        String jarPath = Main.class.getProtectionDomain().getCodeSource().getLocation().getPath();
        InputStream input = null;
        BufferedInputStream bis = null;
        StringBuilder sb = new StringBuilder();
        try {
            JarFile jarFile = new JarFile(jarPath);
            ZipEntry zipEntry = jarFile.getEntry(file);
            //can not find the deserved file
            if (zipEntry == null) {
                logger.info("Can not find file {} in {}", file, jarPath);
                return null;
            }

            input = jarFile.getInputStream(zipEntry);
            bis = new BufferedInputStream(input);

            byte[] temp = new byte[1024];
            int len;
            while ((len = bis.read(temp)) != -1) {
                sb.append(new String(temp, 0, len, StandardCharsets.UTF_8));
            }
        } catch (IOException ex) {
            logger.error("Fail to read file {}:{}", file, ex.getMessage());
            logger.error("Exception:", ex);
            throw new RuntimeException("A valid file " + file + " is unavailable.");
        } finally {
            if (bis != null) {
                bis.close();
            }

            if (input != null) {
                input.close();
            }
        }

        return sb.toString();
    }

上面这种方式,通过jar包的方式来加载文件,通用性更强一些,在前述两种都不可用的时候,往往还是可用的。

posted @ 2020-09-03 16:24  boiledwater  阅读(2600)  评论(0编辑  收藏  举报