Java gets the file and reads the file in the Jar package

This article introduces various ways of java to read files from classpath, url and jar.

Various Ways to Get

Project name: JavaPath
Package name: com.theliang
Description: There is a Main class under the package, and a text file hello.text under the project

insert image description here


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

The results output in 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
测试文件

The output result of executing the JAR package

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
测试文件

Difference map:

insert image description here

The external class reads the configuration file in the Jar package

The path format of the configuration file in the Jar package is:jar:file/地址/Jar包.jar!/配置文件名

Determine whether the class file is executed or the jar file is executed

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

In Class it will output:

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

In the Jar package will output:

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

So we can judge the execution environment by the prefix

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

Guess you like

Origin blog.csdn.net/the_liang/article/details/103957426