Java resource as File
ClassLoader.getResourceAsStream
and Class.getResourceAsStream
are definitely the way to go for loading the resource data. However, I don't believe there's any way of "listing" the contents of an element of the classpath.
In some cases this may be simply impossible - for instance, a ClassLoader
could generate data on the fly, based on what resource name it's asked for. If you look at the ClassLoader
API (which is basically what the classpath mechanism works through) you'll see there isn't anything to do what you want.
If you know you've actually got a jar file, you could load that with ZipInputStream
to find out what's available. It will mean you'll have different code for directories and jar files though.
One alternative, if the files are created separately first, is to include a sort of manifest file containing the list of available resources. Bundle that in the jar file or include it in the file system as a file, and load it before offering the user a choice of resources.
How do I load a file from resource folder?
Try the next:
ClassLoader classloader = Thread.currentThread().getContextClassLoader();
InputStream is = classloader.getResourceAsStream("test.csv");
If the above doesn't work, various projects have been added the following class: ClassLoaderUtil
1 (code here).2
Here are some examples of how that class is used:
src\main\java\com\company\test\YourCallingClass.java
src\main\java\com\opensymphony\xwork2\util\ClassLoaderUtil.java
src\main\resources\test.csv
// java.net.URL
URL url = ClassLoaderUtil.getResource("test.csv", YourCallingClass.class);
Path path = Paths.get(url.toURI());
List<String> lines = Files.readAllLines(path, StandardCharsets.UTF_8);
// java.io.InputStream
InputStream inputStream = ClassLoaderUtil.getResourceAsStream("test.csv", YourCallingClass.class);
InputStreamReader streamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
BufferedReader reader = new BufferedReader(streamReader);
for (String line; (line = reader.readLine()) != null;) {
// Process line
}
Notes
- See it in The Wayback Machine.
- Also in GitHub.
Reading a resource file from within jar
Rather than trying to address the resource as a File just ask the ClassLoader to return an InputStream for the resource instead via getResourceAsStream:
try (InputStream in = getClass().getResourceAsStream("/file.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(in))) {
// Use resource
}
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 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
Using resource files in an executeable jar
The resource packaged in your jar file is not a File but a series of bytes in a zip file. It must be processed has a stream of bytes.
Use getResourceAsStream(...) instead of getResource(...) to get an InputStream instead of File and read the content with an InputStreamReader instead of FileReader.
Don't forget to close resources in a finally block or with a try-with-resources.
Something like that :
public class HelloWorld {
public static void main(String[] args) throws IOException {
try(BufferedReader br = new BufferedReader(new InputStreamReader(HelloWorld.class.getClassLoader().getResourceAsStream("test.txt")))) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
}
}
}
Get resource file from jar file
String fontFilePath = Paths.get(System.getProperty("user.dir"), "prova.jar", "Retro Gaming.ttf").toString();
That.. rather obviously won't work.
You need to use the gRAS (getResourceAsStream) system. File
in java (as in, what new FileInputStream
needs, the java.io.File
object) are actual files. entries inside jar files don't count. It is not possible to refer to that ttf file with a File
object, nor to open it with FileInputStream.
Fortunately, the createFont
method doesn't demand that you pass a FileInputStream
; any old InputStream
will do.
The ttf file needs to be in the same classpath root as the this very class you are writing (for example, the same jar). Once you've ensured that is the case, you can use gRAS:
try (var fontIn = FontLoader.class.getResourceAsStream("/Retro Gaming.ttf")) {
Font.createFont(Font.TRUETYPE_FONT, fontIn).deriveFont(.., ...);
}
gRAS looks in the same place as where FontLoader.class
lives. From your snippet it sounds like you put the ttf in the 'root' of the jar and not next to FontLoader. The leading slash in the string argument to getResourceAsStream
means: Look relative to the root of the place FontLoader is in (so, your jar, presumably).
How to check existence of xml file in resources folder in java?
The src/main/resources
is the root of the classpath (or the files in there are added to the root. So resources/folder/test.xml
would expect a file in src/main/resources/resources/folder/test.xml
. This is probably not what you want. Remove the resources
part in the file path.
Resource resource = new ClassPathResource("/folder/test.xml");
if(resource.exists()) {
System.out.println(" SUCCESS ");
} else {
System.out.println(" FAIL . RESOURCE NOT FOUND");
}
Should do the trick.
How do I get a Java resource as a File?
Apache Commons-IO has an IOUtils class as well as a FileUtils, which includes a readLines
method similar to the one in FileUtils.
So you can use getResourceAsStream
or getSystemResourceAsStream
and pass the result of that to IOUtils.readLines
to get a List<String>
of the contents of your file:
List<String> myLines = IOUtils.readLines(ClassLoader.getSystemResourceAsStream("my_data_file.txt"));
Loading external file as resource
You can add the folder location in the classpath.
java -Dloader.path="/something/something1/" -jar your-app.jar
see link for loader.path
documentation
If you want to load a resource that is not in the classpath, use FileSystemResource
instead of ClassPathResource
so it will load the resource in the file system.
Related Topics
Replace Implicit Wait with Explicit Wait (Selenium Webdriver & Java)
Spring: @Component Versus @Bean
What Exactly Is Field Injection and How to Avoid It
Is There a Destructor for Java
What Is Suppresswarnings ("Unchecked") in Java
How to Connect to Oracle Using Service Name Instead of Sid
Connecting to Remote Url Which Requires Authentication Using Java
Illegalmonitorstateexception on Wait() Call
Why Are Filenames in Java the Same as the Public Class Name
Powermockito Mock Single Static Method and Return Object
How to Switch Between Frames in Selenium Webdriver Using Java
Differencebetween Up-Casting and Down-Casting with Respect to Class Variable
Why Does Runtime.Exec(String) Work for Some But Not All Commands