Rather than trying to address the resource as a File just ask the ClassLoader to return an InputStream for the resource instead via getResourceAsStream:
InputStream in = getClass().getResourceAsStream("/file.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
As long as the file.txt
resource
is available on the classpath then this approach will work the same way regardless of whether the file.txt
resource
is in a classes/
directory
or inside a jar
.
The URI
is not hierarchical
occurs because the URI for a resource within a jar file is going to look like something like this: file:/example.jar!/file.txt
.
You cannot read the entries within a jar
(a zip
file)
like it was a plain old File.
This is explained well by the answers to:
- How do I read a resource file from a Java jar file?
- Java Jar file: use resource errors: URI is not hierarchical
InputStream
s
don't have encodings. They're just streams of bytes. Readers
are for text with an encoding. You can create a Reader
with
a specific charset from an InputStream
like
this:
Reader reader = new InputStreamReader(inputStream, "UTF-8");
If you're using a charset that's guaranteed to be supported on all Java platforms like UTF-8, you can avoid having to deal with impossible UnsupportedEncodingException
s
by using a constant from Guava's Charsets
class
like Charsets.UTF_8
.