在jar文件中访问文件?

16

我需要能够访问存储在已编译的jar文件中的文件。我已经找出了如何将该文件添加到项目中,但是我该如何在代码中引用它?我应该如何将文件从jar文件复制到用户硬盘上的某个位置?我知道有很多种方法可以访问文件(FileInputStream、FileReader等),但我不知道如何查看jar文件内部。

5个回答

29
您可以使用以下代码: InputStream is = this.getClass().getClassLoader().getResourceAsStream(fileFromJarFile); 如果foo.txt在JAR文件的根目录中,您可以使用以下代码: InputStream is = this.getClass().getClassLoader().getResourceAsStream("foo.txt"); 假设该类与资源位于同一JAR文件中。

我需要的一部分是 BufferedReader,它需要一个 FileReader 作为输入。如何将 InputStream 转换为 FileReader? - LRFLEW
你只需要在Java文档中连接点进行操作。看一下BufferedReader - 在“另请参阅”部分,有FileReader和InputStreamReader。转到InputStreamReader等。 - typo.pl
是的,我可以做到,但我刚查了一下 BufferedReader,发现了它的伴侣类 BufferInputStream,这才是我需要使用的:P。 - LRFLEW
有趣的是:... getResourceAsStream("foo.txt"); 对我不起作用,但是改为 getResourceAsStream("/foo.txt"); 就可以了。 - ShadowGames

6
你可以使用getResource()获取类路径上文件的URL,或者使用getResourceAsStream()获取InputStream。

例如:

BufferedReader reader = new BufferedReader(new InputStreamReader(
    this.getClass().getResourceAsStream("foo.txt")));

5

使用JarFile类,您可以读取JAR文件的内容。

以下是一个示例,展示如何从JAR文件中获取特定文件并提取它:

JarFile jar = new JarFile("foo.jar");
String file = "file.txt";
JarEntry entry = jar.getEntry(file);
InputStream input = jar.getInputStream(entry);
OutputStream output = new FileOutputStream(file);
try {
    byte[] buffer = new byte[input.available()];
    for (int i = 0; i != -1; i = input.read(buffer)) {
        output.write(buffer, 0, i);
    }
} finally {
    jar.close();
    input.close();
    output.close();
}

我认为 OP 的意思是编译后的 jar 文件中包含一个文件。 - sam1370
@Sam1370:是的。这个能做到吗? - someguy

1

我想补充一点,如果我们想访问位于以下路径的JAR文件中的文件(仅为资源加载提供示例,并且与操作系统无关):

Windows:  
c:\your-jar-file.jar\dir1\dir2\dir3\foo.txt

Linux: 
/home/your-jar-file.jar/dir1/dir2/dir3/foo.txt

需要使用以下代码(注意路径开头没有“/”字符):

InputStream is = this.getClass().getClassLoader().getResourceAsStream("dir1/dir2/dir3/foo.txt");

getResourceAsStream 如何知道要查找 c:\your-jar-file.jar 中的内容?如果 jar 文件与程序正在运行的 jar 文件完全分离,会怎样呢? - Michael Sims
我在这里举了一些真实的操作系统相关路径的例子,以便理解资源路径语法与操作系统绝对路径的关系。你说得对,java.lang.ClassLoader.getResourceAsStream只能从由你运行的JVM管理的jar中加载资源。我喜欢将路径以其绝对形式来考虑,这样你就可以理解最复杂的情况是如何被解析的。所有这些jar资源的加载都很方便,如果你想要在其中包含资源并且具有操作系统独立性。 - Constantin Zagorsky
如果您想访问与JVM加载类路径完全分离的jar文件,仍然需要将该jar加载到需要它的JVM进程中,最简单的方法是在类路径上定义它。它可以以编程方式加载(https://dev59.com/w2435IYBdhLWcg3w20B8#5172103),这是一个不同的主题,在大多数情况下不需要,因为Java已经使用其默认的类加载器为您完成了很好的工作。 - Constantin Zagorsky

-1
看一下JarFile类。你需要获取jar文件中特定条目的InputStream所需的一切都在那里。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接