欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【Java总结】如何读取Jar包中文件内容

程序员文章站 2022-05-04 16:40:55
...

需求说明

  • 我想利用标准输入流、输出流写文件
  • 我想在开发模式下读取Properties文件,想打成可执行Jar包时读取Jar包内的Properties文件

需求分解与实现

1. 标准输入流写文件

public static final InputStream in"标准"输入流。

示例:通过字符缓冲流来获取键盘录入的数据,落入文件

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;

public class TestInputStreamWrite {

    public static void main(String[] args) {
        BufferedReader br = null;
        PrintWriter pw = null;

        try {
            br = new BufferedReader(new InputStreamReader(System.in));
            pw = new PrintWriter(new BufferedWriter(new FileWriter("./std.in")));
            String str = null;
            while((str=br.readLine())!=null){
                if (str.equals("quit")){
                    System.out.println("谢谢使用!");
                    break;
                }
                pw.println(str);
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally{
            try {
                if (br!=null) br.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(pw!=null) pw.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }

}

2. 标准输出流写文件
示例:通过打印流PrintStream,格式化写入文件

import java.io.* ;
public class PrintDemo02{
    public static void main(String arg[]) throws Exception{
        PrintStream ps = null ;     // 声明打印流对象
        // 如果现在是使用FileOuputStream实例化,意味着所有的输出是向文件之中
        ps = new PrintStream(new FileOutputStream(new File("d:" + File.separator + "test.txt"))) ;
        String name = "刘勋" ;    // 定义字符串
        int age = 23 ;              // 定义整数
        float score = 990.356f ;    // 定义小数
        char sex = 'M' ;            // 定义字符
        ps.printf("姓名:%s;年龄:%d;成绩:%f;性别:%c",name,age,score,sex) ;
        ps.close() ;
    }
}

PS:还有其他用法,请自行搜索。

3. 如何判断是class文件执行还是jar文件执行
要点是用Class.getResource方法来获取该类文件的位置:

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

如果是.class文件启动:

file:/C:/Users/Jon/Test/com/whatever/Foo.class

如果是从jar包启动:

jar:file:/C:/Users/Jon/Test/foo.jar!/com/whatever/Foo.class

所以,这样就简单了:

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

4. 如何加载jar包中的Properties文件
要点一:开发调试模式下,使用jdk自带的Properties工具类加载Properties文件

Properties prop = new Properties();
// 获取Properties文件的绝对路径
// getResourec中的参数是相对classpath的位置
String basPath = Foo.class.getClassLoader().getResource("test.properties").getPath().toString();
// 标准输入流
InputStream in = new BufferedInputStream(new FileInputStream(new File(basPath)));
prop.load(in);

要点二:打成可执行jar包时,如何加载Properties文件

使用类路径

String path = this.getClass().getProtectionDomain().getCodeSource().getLocation().getPath();

或者

String jarPath = this.getClass().getProtectionDomain().getCodeSource().getLocation().getFile();

因为程序已经被打包成jar包,所以getPath()和getFile()在这里的返回值是一样的。都是/xxx/xxx.jar这种形式。如果路径包含Unicode字符,还需要将路径转码。

jarPath = java.net.URLDecoder.decode(jarPath, "UTF-8");

加载特定资源文件

// 路径拼接
URL url = new URL("jar:file" + jarPath + "!/resources/test.properties");
// 标准输入流
InputStream in = url.openStream();
prop.load(in);

至此,完成。仅作记录