Reputation: 1002
I have a Maven project in which I have a class SomeClass
in src/main/java
that is supposed to read out a file located in src/main/resources
.
This was my first approach:
private static void someMethod() {
// ... [context] ...
String fileName = "src/main/resources/some_file.txt";
for(String line : Files.readAllLines(Paths.get(fileName))) {
System.out.println(line);
}
}
This works fine when run on the Eclipse console, but it doesn't when I execute the jar-file (produced by Maven) on the Windows console (an IOException
is thrown).
I thought it'd have to do with the file path, so I changed the code to this:
private static void someMethod() {
// ... [context] ...
String fileName = "C:/Users/.../workspace/.../src/main/resources/some_file.txt";
for(String line : Files.readAllLines(Paths.get(fileName))) {
System.out.println(line);
}
}
This works on both, the Eclipse- and Windows console. But clearly this won't work on another machine.
Upon search I've changed the static method to be non-static, and used ClassLaoder
to get the file:
private void someMethod() {
// ... [context] ...
ClassLoader cL = getClass().getClassLoader();
File file = new File(cL.getResource("some_file.txt").getFile());
for(String line : Files.readAllLines(Paths.get(file.getPath()))) { // or getAbsolutePath()
System.out.println(line);
}
}
This one works on the Eclipse console, and when I System.out.println(file.getPath)
it prints out the correct path. But it doesn't work on the Windows console. When executing the jar-file, I get this:
Exception in thread "main" java.nio.file.InvalidPathException: Illegal char <:> at index 4: file:\C:\Users\...\target\...-SNAPSHOT.jar!\some_file.txt
at sun.nio.fs.WindowsPathParser.normalize(Unknown Source)
at sun.nio.fs.WindowsPathParser.parse(Unknown Source)
at sun.nio.fs.WindowsPathParser.parse(Unknown Source)
at sun.nio.fs.WindowsPath.parse(Unknown Source)
at sun.nio.fs.WindowsFileSystem.getPath(Unknown Source)
at java.io.File.toPath(Unknown Source)
...
So, long story cut short: how can I specify the file-path, so that the jar-file produced by the Maven build executes correctly, independent of the platform it's run on?
Upvotes: 3
Views: 1012
Reputation: 137329
Since you are trying to read from a classpath resource (i.e. a resource that is not in the file system but embedded in a jar, as indicated by src/main/resources
), you can't use Files.lines
. A Java NIO.2 Path
can't be used for a resource inside a JAR.
You need to use an InputStream
instead. To read all the lines from a file, you can wrap it into a BufferedReader
. Assuming this code is inside the class SomeClass
, you could have the following (Java 8):
try (BufferedReader br = new BufferedReader(new InputStreamReader(SomeClass.class.getResourceAsStream("/some_file.txt")))) {
br.lines().forEach(System.out::println);
}
Upvotes: 6