Java 获取文件Jar包中读取文件

本文介绍java多种方式从classpath、url以及jar中读取文件。

各种路径获取方式

项目名:JavaPath
包名:com.theliang
说明:包下有一个 Main类,项目下有一个hello.text的文本文件

在这里插入图片描述


package com.theliang;

import java.io.File;
import java.io.InputStream;
import java.net.URL;

public class Main {
    
    

    public static void main(String[] args) throws Exception {
    
    
        //* 1. 获取项目的路径(非Jar包)
        String path1 = System.getProperty("user.dir");
        System.out.println("1.获取项目的路径 = " + path1);
        //* 1. 获取项目的主路径(包级以上级别)(非Jar包)
        String path1_1 = Main.class.getClassLoader().getResource(".").getFile();
        System.out.println("1.获取项目的路径 = " + path1_1);
        //* 2. 获取项目中当前类的路径(非Jar包)
        String path2 = Main.class.getResource("Main.class").getPath();
        System.out.println("2.获取项目中当前类的路径 = " + path2);
        //* 3. 获取Jar包所在路径
        String path3 = System.getProperty("user.dir");
        System.out.println("3.获取Jar包所在路径 = " + path3);
        //* 4. 获取Jar包路径
        String path4 = Main.class.getProtectionDomain().getCodeSource().getLocation().getFile();
        String path4_1 = Main.class.getProtectionDomain().getCodeSource().getLocation().getPath();//两个是相同的
        System.out.println("4.获取Jar包路径 = " + path4);
        System.out.println("4.获取Jar包路径 = " + path4_1);
        //* 5. 获取Jar包中指定资源的路径
        String path5 = Main.class.getClassLoader().getResource("hello.text").getPath();
        String path5_1 = Main.class.getClassLoader().getResource("hello.text").getFile();
        System.out.println("5.获取Jar包中指定资源的路径 = " + path5);
        System.out.println("5.获取Jar包中指定资源的路径 = " + path5_1);
        //* 6. 读取项目下的文件(非Jar包)
        URL url = Main.class.getClassLoader().getResource("hello.text");
        System.out.println("6.读取项目下的文件 = " + url.getPath());
        InputStream is = url.openStream();
//        is = Main.class.getClassLoader().getResourceAsStream("hello.text");//也可以写成这样
        byte[] bytes = new byte[1024];
        while (is.read(bytes) != -1) {
    
    
            System.out.println(new String(bytes, "UTF-8"));
        }

        //* 7. 读取Jar包中的文件(执行的类也在相同的jar包中)
        URL url2 = Main.class.getClassLoader().getResource("hello.text");
        System.out.println("7.读取Jar包中的文件 = " + url2.getPath());
        InputStream is2 = url2.openStream();
        byte[] bytes2 = new byte[1024];
        while (is2.read(bytes2) != -1) {
    
    
            System.out.println(new String(bytes2, "UTF-8"));
        }

        //* 8. 外部类访问Jar包内的文件
        String jarPath = "D:/Project/JavaPath/out/artifacts/JavaPath_jar/JavaPath.jar";
        URL url3 = new URL("jar:file:/" + jarPath + "!/hello.text");
        System.out.println("8.访问Jar包内的文件 = " + url3.getPath());
        InputStream is3 = url3.openStream();
        byte[] bytes3 = new byte[1024];
        while (is3.read(bytes3) != -1) {
    
    
            System.out.println(new String(bytes3, "UTF-8"));
        }

        //* 9. 乱码问题
        //如果路径包含Unicode字符,还需要将路径转码
        path1 = java.net.URLDecoder.decode(path1, "UTF-8");
    }
}

IDEA中输出的结果

1.获取项目的路径 = D:\Project\JavaPath
2.获取项目中当前类的路径 = /D:/Project/JavaPath/out/production/JavaPath/com/theliang/Main.class
3.获取Jar包所在路径 = D:\Project\JavaPath
4.获取Jar包路径 = /D:/Project/JavaPath/out/production/JavaPath/
4.获取Jar包路径 = /D:/Project/JavaPath/out/production/JavaPath/
5.获取Jar包中指定资源的路径 = /D:/Project/JavaPath/out/production/JavaPath/hello.text
5.获取Jar包中指定资源的路径 = /D:/Project/JavaPath/out/production/JavaPath/hello.text
6.读取项目下的文件 = /D:/Project/JavaPath/out/production/JavaPath/hello.text
Hello Test
测试文件
7.读取Jar包中的文件 = /D:/Project/JavaPath/out/production/JavaPath/hello.text
Hello Test
测试文件
8.访问Jar包内的文件 = file:/D:/Project/JavaPath/out/artifacts/JavaPath_jar/JavaPath.jar!/hello.text
Hello Test
测试文件

执行JAR包所输出的结果

1.获取项目的路径 = D:\Project\JavaPath\out\artifacts\JavaPath_jar
2.获取项目中当前类的路径 = file:/D:/Project/JavaPath/out/artifacts/JavaPath_jar/JavaPath.jar!/com/theliang/Main.class
3.获取Jar包所在路径 = D:\Project\JavaPath\out\artifacts\JavaPath_jar
4.获取Jar包路径 = /D:/Project/JavaPath/out/artifacts/JavaPath_jar/JavaPath.jar
4.获取Jar包路径 = /D:/Project/JavaPath/out/artifacts/JavaPath_jar/JavaPath.jar
5.获取Jar包中指定资源的路径 = file:/D:/Project/JavaPath/out/artifacts/JavaPath_jar/JavaPath.jar!/hello.text
5.获取Jar包中指定资源的路径 = file:/D:/Project/JavaPath/out/artifacts/JavaPath_jar/JavaPath.jar!/hello.text
6.读取项目下的文件 = file:/D:/Project/JavaPath/out/artifacts/JavaPath_jar/JavaPath.jar!/hello.text
Hello Test
测试文件
7.读取Jar包中的文件 = file:/D:/Project/JavaPath/out/artifacts/JavaPath_jar/JavaPath.jar!/hello.text
Hello Test
测试文件
8.访问Jar包内的文件 = file:/D:/Project/JavaPath/out/artifacts/JavaPath_jar/JavaPath.jar!/hello.text
Hello Test
测试文件

差异图:

在这里插入图片描述

外部类读取Jar包中的配置文件

Jar包中配置文件的路径格式是:jar:file/地址/Jar包.jar!/配置文件名

判断 是class文件执行还是jar文件执行

public class Main {
    
    
    public static void main(String[] args) {
    
    
        System.out.println(Main.class.getResource("Main.class").toString());
    }
}

在Class中会输出:

file:/D:/Project/JavaPath/out/production/JavaPath/com/theliang/Main.class

在Jar包中会输出:

jar:file:/D:/Project/JavaPath/out/production/JavaPath/com/theliang/JavaPath.jar!/com/theliang/Main.class

所以我们可以通过前缀判断执行环境

String filePath = Main.class.getResource("Main.class").toString();
// true: jar文件启动
// false: class文件启动
boolean road = filePath.startsWith("jar:file");

猜你喜欢

转载自blog.csdn.net/the_liang/article/details/103957426