访问资源文件的 Maven 问题
Maven Issue With Accessing Resource File
我正在尝试使用 Maven 构建一个 JAR 文件,该文件将在 运行 时间内从文件系统加载文件。使用
编译后加载文件时遇到问题
mvn clean package
pom.xml:
<build>
<resources>
<resource>
<filtering>true</filtering>
<directory>src/main/resources</directory>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>App</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>7</source>
<target>7</target>
</configuration>
</plugin>
</plugins>
</build>
我的主要 Class 是:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
public class App {
public static void main(String[] args) throws IOException {
App app = new App();
app.printTestFile();
}
public void printTestFile() throws IOException {
File file = new File(getClass().getClassLoader().getResource("template.txt").getFile());
System.out.println("File is in " + file.getAbsolutePath());
printFile(file);
}
private static void printFile(File file) throws IOException {
try (FileReader reader = new FileReader(file);
BufferedReader br = new BufferedReader(reader)) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
}
}
}
文件载入:
File file = new File(getClass().getClassLoader().getResource("template.txt").getFile());
项目结构为:
│ pom.xml
└───src
├───main
│ ├───java
│ │ App.java
│ └───resources
│ template.txt
└───test
└───java
当 运行 使用 IntelliJ 时,结果是:
File is in C:\Users\user\Documents\Git\maven-scratch\target\classes\template.txt
This is the test file's content.
但是,当 运行 完全使用 Maven 时,问题就来了,例如:
mvn clean package
java -jar target\maven-scratch-1.0-SNAPSHOT.jar
输出错误:
File is in C:\Users\user\Documents\Git\maven-scratch\file:\C:\Users\user\Documents\Git\maven-scratch\target\maven-scratch-1.0-SNAPSHOT.jar!\template.txt
Exception in thread "main" java.io.FileNotFoundException: file:\C:\Users\user\Documents\Git\maven-scratch\target\maven-scratch-1.0-SNAPSHOT.jar!\template.txt (The filena
me, directory name, or volume label syntax is incorrect)
at java.io.FileInputStream.open0(Native Method)
at java.io.FileInputStream.open(Unknown Source)
at java.io.FileInputStream.<init>(Unknown Source)
at java.io.FileReader.<init>(Unknown Source)
at App.printFile(App.java:19)
at App.printTestFile(App.java:15)
at App.main(App.java:9)
最让我困惑的是试图加载的文件具有路径:
C:\Users\user\Documents\Git\maven-scratch\file:\C:\Users\user\Documents\Git\maven-scratch\target\maven-scratch-1.0-SNAPSHOT.jar!\template.txt
...是否使用 IntelliJ 路径是:
C:\Users\user\Documents\Git\maven-scratch\target\classes\template.txt
有没有一种简单的方法可以使用 Maven 的资源文件夹中的文件,并在使用 Maven 打包到 JAR 后也能够从目标目录中读取文件?
使用maven assembly plugin生成目标jar可以帮助您解决这个问题。
maven assembly
JAR 结构很好(通过将其加载到 zip 文件查看器中可以轻松验证)。
IntelliJ 的类路径是 本地文件系统 - 它正在加载一个真实的文件 ./target/classes/template.txt
命令行类路径在 JAR 文件 (maven-scratch-1.0-SNAPSHOT.jar!\template.txt
) 中寻找相同的东西。这不是实际文件本身,它是 JAR 文件 中的一些字节。基本上它不能被 FileReader
读取,它正在寻找一个字面上名为 maven-scratch-1.0-SNAPSHOT.jar!\template.txt
的文件
// getResourceAsStream doesn't care if it comes from a real file or a jar
InputStream is = getClass().getClassLoader().getResourceAsStream("fix.cfg");
InputStreamReader reader = new InputStreamReader(is);
我正在尝试使用 Maven 构建一个 JAR 文件,该文件将在 运行 时间内从文件系统加载文件。使用
编译后加载文件时遇到问题 mvn clean package
pom.xml:
<build>
<resources>
<resource>
<filtering>true</filtering>
<directory>src/main/resources</directory>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>App</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>7</source>
<target>7</target>
</configuration>
</plugin>
</plugins>
</build>
我的主要 Class 是:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
public class App {
public static void main(String[] args) throws IOException {
App app = new App();
app.printTestFile();
}
public void printTestFile() throws IOException {
File file = new File(getClass().getClassLoader().getResource("template.txt").getFile());
System.out.println("File is in " + file.getAbsolutePath());
printFile(file);
}
private static void printFile(File file) throws IOException {
try (FileReader reader = new FileReader(file);
BufferedReader br = new BufferedReader(reader)) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
}
}
}
文件载入:
File file = new File(getClass().getClassLoader().getResource("template.txt").getFile());
项目结构为:
│ pom.xml
└───src
├───main
│ ├───java
│ │ App.java
│ └───resources
│ template.txt
└───test
└───java
当 运行 使用 IntelliJ 时,结果是:
File is in C:\Users\user\Documents\Git\maven-scratch\target\classes\template.txt
This is the test file's content.
但是,当 运行 完全使用 Maven 时,问题就来了,例如:
mvn clean package
java -jar target\maven-scratch-1.0-SNAPSHOT.jar
输出错误:
File is in C:\Users\user\Documents\Git\maven-scratch\file:\C:\Users\user\Documents\Git\maven-scratch\target\maven-scratch-1.0-SNAPSHOT.jar!\template.txt
Exception in thread "main" java.io.FileNotFoundException: file:\C:\Users\user\Documents\Git\maven-scratch\target\maven-scratch-1.0-SNAPSHOT.jar!\template.txt (The filena
me, directory name, or volume label syntax is incorrect)
at java.io.FileInputStream.open0(Native Method)
at java.io.FileInputStream.open(Unknown Source)
at java.io.FileInputStream.<init>(Unknown Source)
at java.io.FileReader.<init>(Unknown Source)
at App.printFile(App.java:19)
at App.printTestFile(App.java:15)
at App.main(App.java:9)
最让我困惑的是试图加载的文件具有路径:
C:\Users\user\Documents\Git\maven-scratch\file:\C:\Users\user\Documents\Git\maven-scratch\target\maven-scratch-1.0-SNAPSHOT.jar!\template.txt
...是否使用 IntelliJ 路径是:
C:\Users\user\Documents\Git\maven-scratch\target\classes\template.txt
有没有一种简单的方法可以使用 Maven 的资源文件夹中的文件,并在使用 Maven 打包到 JAR 后也能够从目标目录中读取文件?
使用maven assembly plugin生成目标jar可以帮助您解决这个问题。 maven assembly
JAR 结构很好(通过将其加载到 zip 文件查看器中可以轻松验证)。
IntelliJ 的类路径是 本地文件系统 - 它正在加载一个真实的文件 ./target/classes/template.txt
命令行类路径在 JAR 文件 (maven-scratch-1.0-SNAPSHOT.jar!\template.txt
) 中寻找相同的东西。这不是实际文件本身,它是 JAR 文件 中的一些字节。基本上它不能被 FileReader
读取,它正在寻找一个字面上名为 maven-scratch-1.0-SNAPSHOT.jar!\template.txt
// getResourceAsStream doesn't care if it comes from a real file or a jar
InputStream is = getClass().getClassLoader().getResourceAsStream("fix.cfg");
InputStreamReader reader = new InputStreamReader(is);