My project has the following structure:
/src/main/java/
/src/main/resources/
/src/test/java/
/src/test/resources/
I have a file in /src/test/resources/test.csv and I want to load the file from a unit test in /src/test/java/MyTest.java
I have this code which didn't work. It complains "No such file or directory".
BufferedReader br = new BufferedReader (new FileReader(test.csv))
I also tried this
InputStream is = (InputStream) MyTest.class.getResourcesAsStream(test.csv))
This also doesn't work. It returns null. I am using Maven to build my project.
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: ClassLoaderUtil1 (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.
Try:
InputStream is = MyTest.class.getResourceAsStream("/test.csv");
IIRC getResourceAsStream() by default is relative to the class's package.
As #Terran noted, don't forget to add the / at the starting of the filename
Try following codes on Spring project
ClassPathResource resource = new ClassPathResource("fileName");
InputStream inputStream = resource.getInputStream();
Or on non spring project
ClassLoader classLoader = getClass().getClassLoader();
File file = new File(classLoader.getResource("fileName").getFile());
InputStream inputStream = new FileInputStream(file);
Here is one quick solution with the use of Guava:
import com.google.common.base.Charsets;
import com.google.common.io.Resources;
public String readResource(final String fileName, Charset charset) throws IOException {
return Resources.toString(Resources.getResource(fileName), charset);
}
Usage:
String fixture = this.readResource("filename.txt", Charsets.UTF_8)
Non spring project:
String filePath = Objects.requireNonNull(getClass().getClassLoader().getResource("any.json")).getPath();
Stream<String> lines = Files.lines(Paths.get(filePath));
Or
String filePath = Objects.requireNonNull(getClass().getClassLoader().getResource("any.json")).getPath();
InputStream in = new FileInputStream(filePath);
For spring projects, you can also use one line code to get any file under resources folder:
File file = ResourceUtils.getFile(ResourceUtils.CLASSPATH_URL_PREFIX + "any.json");
String content = new String(Files.readAllBytes(file.toPath()));
For java after 1.7
List<String> lines = Files.readAllLines(Paths.get(getClass().getResource("test.csv").toURI()));
Alternatively you can use Spring utils if you are in Spring echosystem
final val file = ResourceUtils.getFile("classpath:json/abcd.json");
To get to more behind the scene, check out following blog
https://todzhang.com/blogs/tech/en/save_resources_to_files
I faced the same issue.
The file was not found by a class loader, which means it was not packed into the artifact (jar). You need to build the project. For example, with maven:
mvn clean package
So the files you added to resources folder will get into maven build and become available to the application.
I would like to keep my answer: it does not explain how to read a file (other answers do explain that), it answers why InputStream or resource was null. Similar answer is here.
ClassLoader loader = Thread.currentThread().getContextClassLoader();
InputStream is = loader.getResourceAsStream("test.csv");
If you use context ClassLoader to find a resource then definitely it will cost application performance.
Now I am illustrating the source code for reading a font from maven created resources directory,
scr/main/resources/calibril.ttf
Font getCalibriLightFont(int fontSize){
Font font = null;
try{
URL fontURL = OneMethod.class.getResource("/calibril.ttf");
InputStream fontStream = fontURL.openStream();
font = new Font(Font.createFont(Font.TRUETYPE_FONT, fontStream).getFamily(), Font.PLAIN, fontSize);
fontStream.close();
}catch(IOException | FontFormatException ief){
font = new Font("Arial", Font.PLAIN, fontSize);
ief.printStackTrace();
}
return font;
}
It worked for me and hope that the entire source code will also help you, Enjoy!
Import the following:
import java.io.IOException;
import java.io.FileNotFoundException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.InputStream;
import java.util.ArrayList;
The following method returns a file in an ArrayList of Strings:
public ArrayList<String> loadFile(String filename){
ArrayList<String> lines = new ArrayList<String>();
try{
ClassLoader classloader = Thread.currentThread().getContextClassLoader();
InputStream inputStream = classloader.getResourceAsStream(filename);
InputStreamReader streamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
BufferedReader reader = new BufferedReader(streamReader);
for (String line; (line = reader.readLine()) != null;) {
lines.add(line);
}
}catch(FileNotFoundException fnfe){
// process errors
}catch(IOException ioe){
// process errors
}
return lines;
}
getResource() was working fine with the resources files placed in src/main/resources only. To get a file which is at the path other than src/main/resources say src/test/java you need to create it exlicitly.
the following example may help you
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
public class Main {
public static void main(String[] args) throws URISyntaxException, IOException {
URL location = Main.class.getProtectionDomain().getCodeSource().getLocation();
BufferedReader br = new BufferedReader(new FileReader(location.getPath().toString().replace("/target/classes/", "/src/test/java/youfilename.txt")));
}
}
You can use the com.google.common.io.Resources.getResource to read the url of file and then get the file content using java.nio.file.Files to read the content of file.
URL urlPath = Resources.getResource("src/main/resource");
List<String> multilineContent= Files.readAllLines(Paths.get(urlPath.toURI()));
if you are loading file in static method then
ClassLoader classLoader = getClass().getClassLoader();
this might give you an error.
You can try this
e.g. file you want to load from resources is resources >> Images >> Test.gif
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
Resource resource = new ClassPathResource("Images/Test.gif");
File file = resource.getFile();
To read the files from src/resources folder then try this :
DataSource fds = new FileDataSource(getFileHandle("images/sample.jpeg"));
public static File getFileHandle(String fileName){
return new File(YourClassName.class.getClassLoader().getResource(fileName).getFile());
}
in case of non static reference:
return new File(getClass().getClassLoader().getResource(fileName).getFile());
Does the code work when not running the Maven-build jar, for example when running from your IDE? If so, make sure the file is actually included in the jar. The resources folder should be included in the pom file, in <build><resources>.
The following class can be used to load a resource from the classpath and also receive a fitting error message in case there's a problem with the given filePath.
import java.io.InputStream;
import java.nio.file.NoSuchFileException;
public class ResourceLoader
{
private String filePath;
public ResourceLoader(String filePath)
{
this.filePath = filePath;
if(filePath.startsWith("/"))
{
throw new IllegalArgumentException("Relative paths may not have a leading slash!");
}
}
public InputStream getResource() throws NoSuchFileException
{
ClassLoader classLoader = this.getClass().getClassLoader();
InputStream inputStream = classLoader.getResourceAsStream(filePath);
if(inputStream == null)
{
throw new NoSuchFileException("Resource file not found. Note that the current directory is the source folder!");
}
return inputStream;
}
}
this.getClass().getClassLoader().getResource("filename").getPath()
My file in the test folder could not be found even though I followed the answers. It got resolved by rebuilding the project. It seems IntelliJ did not recognize the new file automatically. Pretty nasty to find out.
I got it work on both running jar and in IDE by writing as
InputStream schemaStream =
ProductUtil.class.getClassLoader().getResourceAsStream(jsonSchemaPath);
byte[] buffer = new byte[schemaStream.available()];
schemaStream.read(buffer);
File tempFile = File.createTempFile("com/package/schema/testSchema", "json");
tempFile.deleteOnExit();
FileOutputStream out = new FileOutputStream(tempFile);
out.write(buffer);
This worked pretty fine for me :
InputStream in = getClass().getResourceAsStream("/main/resources/xxx.xxx");
InputStreamReader streamReader = new InputStreamReader(in, StandardCharsets.UTF_8);
BufferedReader reader = new BufferedReader(streamReader);
String content = "";
for (String line; (line = reader.readLine()) != null;) {
content += line;
}
I get it to work without any reference to "class" or "ClassLoader".
Let's say we have three scenarios with the location of the file 'example.file' and your working directory (where your app executes) is home/mydocuments/program/projects/myapp:
a)A sub folder descendant to the working directory:
myapp/res/files/example.file
b)A sub folder not descendant to the working directory:
projects/files/example.file
b2)Another sub folder not descendant to the working directory:
program/files/example.file
c)A root folder:
home/mydocuments/files/example.file (Linux; in Windows replace home/ with C:)
1) Get the right path:
a)String path = "res/files/example.file";
b)String path = "../projects/files/example.file"
b2)String path = "../../program/files/example.file"
c)String path = "/home/mydocuments/files/example.file"
Basically, if it is a root folder, start the path name with a leading slash.
If it is a sub folder, no slash must be before the path name. If the sub folder is not descendant to the working directory you have to cd to it using "../". This tells the system to go up one folder.
2) Create a File object by passing the right path:
File file = new File(path);
3) You are now good to go:
BufferedReader br = new BufferedReader(new FileReader(file));
Related
I would like to read a resource from within my jar like so:
File file;
file = new File(getClass().getResource("/file.txt").toURI());
BufferedReader reader = new BufferedReader(new FileReader(file));
//Read the file
and it works fine when running it in Eclipse, but if I export it to a jar, and then run it, there is an IllegalArgumentException:
Exception in thread "Thread-2"
java.lang.IllegalArgumentException: URI is not hierarchical
and I really don't know why but with some testing I found if I change
file = new File(getClass().getResource("/file.txt").toURI());
to
file = new File(getClass().getResource("/folder/file.txt").toURI());
then it works the opposite (it works in jar but not eclipse).
I'm using Eclipse and the folder with my file is in a class folder.
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
To access a file in a jar you have two options:
Place the file in directory structure matching your package name (after extracting .jar file, it should be in the same directory as .class file), then access it using getClass().getResourceAsStream("file.txt")
Place the file at the root (after extracting .jar file, it should be in the root), then access it using Thread.currentThread().getContextClassLoader().getResourceAsStream("file.txt")
The first option may not work when jar is used as a plugin.
I had this problem before and I made fallback way for loading. Basically first way work within .jar file and second way works within eclipse or other IDE.
public class MyClass {
public static InputStream accessFile() {
String resource = "my-file-located-in-resources.txt";
// this is the path within the jar file
InputStream input = MyClass.class.getResourceAsStream("/resources/" + resource);
if (input == null) {
// this is how we load file within editor (eg eclipse)
input = MyClass.class.getClassLoader().getResourceAsStream(resource);
}
return input;
}
}
Up until now (December 2017), this is the only solution I found which works both inside and outside the IDE.
Use PathMatchingResourcePatternResolver
Note: it works also in spring-boot
In this example I'm reading some files located in src/main/resources/my_folder:
try {
// Get all the files under this inner resource folder: my_folder
String scannedPackage = "my_folder/*";
PathMatchingResourcePatternResolver scanner = new PathMatchingResourcePatternResolver();
Resource[] resources = scanner.getResources(scannedPackage);
if (resources == null || resources.length == 0)
log.warn("Warning: could not find any resources in this scanned package: " + scannedPackage);
else {
for (Resource resource : resources) {
log.info(resource.getFilename());
// Read the file content (I used BufferedReader, but there are other solutions for that):
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(resource.getInputStream()));
String line = null;
while ((line = bufferedReader.readLine()) != null) {
// ...
// ...
}
bufferedReader.close();
}
}
} catch (Exception e) {
throw new Exception("Failed to read the resources folder: " + e.getMessage(), e);
}
The problem is that certain third party libraries require file pathnames rather than input streams. Most of the answers don't address this issue.
In this case, one workaround is to copy the resource contents into a temporary file. The following example uses jUnit's TemporaryFolder.
private List<String> decomposePath(String path){
List<String> reversed = Lists.newArrayList();
File currFile = new File(path);
while(currFile != null){
reversed.add(currFile.getName());
currFile = currFile.getParentFile();
}
return Lists.reverse(reversed);
}
private String writeResourceToFile(String resourceName) throws IOException {
ClassLoader loader = getClass().getClassLoader();
InputStream configStream = loader.getResourceAsStream(resourceName);
List<String> pathComponents = decomposePath(resourceName);
folder.newFolder(pathComponents.subList(0, pathComponents.size() - 1).toArray(new String[0]));
File tmpFile = folder.newFile(resourceName);
Files.copy(configStream, tmpFile.toPath(), REPLACE_EXISTING);
return tmpFile.getAbsolutePath();
}
In my case I finally made it with
import java.lang.Thread;
import java.io.BufferedReader;
import java.io.InputStreamReader;
final BufferedReader in = new BufferedReader(new InputStreamReader(
Thread.currentThread().getContextClassLoader().getResourceAsStream("file.txt"))
); // no initial slash in file.txt
Make sure that you work with the correct separator. I replaced all / in a relative path with a File.separator. This worked fine in the IDE, however did not work in the build JAR.
I have found a fix
BufferedReader br = new BufferedReader(new InputStreamReader(Main.class.getResourceAsStream(path)));
Replace "Main" with the java class you coded it in. replace "path" with the path within the jar file.
for example, if you put State1.txt in the package com.issac.state, then type the path as "/com/issac/state/State1" if you run Linux or Mac. If you run Windows then type the path as "\com\issac\state\State1". Don't add the .txt extension to the file unless the File not found exception occurs.
This code works both in Eclipse and in Exported Runnable JAR
private String writeResourceToFile(String resourceName) throws IOException {
File outFile = new File(certPath + File.separator + resourceName);
if (outFile.isFile())
return outFile.getAbsolutePath();
InputStream resourceStream = null;
// Java: In caso di JAR dentro il JAR applicativo
URLClassLoader urlClassLoader = (URLClassLoader)Cypher.class.getClassLoader();
URL url = urlClassLoader.findResource(resourceName);
if (url != null) {
URLConnection conn = url.openConnection();
if (conn != null) {
resourceStream = conn.getInputStream();
}
}
if (resourceStream != null) {
Files.copy(resourceStream, outFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
return outFile.getAbsolutePath();
} else {
System.out.println("Embedded Resource " + resourceName + " not found.");
}
return "";
}
finally i solved errors:
String input_path = "resources\\file.txt";
input_path = input_path.replace("\\", "/"); // doesn't work with back slash
URL file_url = getClass().getClassLoader().getResource(input_path);
String file_path = new URI(file_url.toString().replace(" ","%20")).getSchemeSpecificPart();
InputStream file_inputStream = file_url.openStream();
You can use class loader which will read from classpath as ROOT path (without "/" in the beginning)
InputStream in = getClass().getClassLoader().getResourceAsStream("file.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
For some reason classLoader.getResource() always returned null when I deployed the web application to WildFly 14. getting classLoader from getClass().getClassLoader() or Thread.currentThread().getContextClassLoader() returns null.
getClass().getClassLoader() API doc says,
"Returns the class loader for the class. Some implementations may use null to represent the bootstrap class loader. This method will return null in such implementations if this class was loaded by the bootstrap class loader."
may be if you are using WildFly and yours web application try this
request.getServletContext().getResource() returned the resource url. Here request is an object of ServletRequest.
If you are using spring, then you can use the the following method to read file from src/main/resources:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import org.springframework.core.io.ClassPathResource;
public String readFileToString(String path) throws IOException {
StringBuilder resultBuilder = new StringBuilder("");
ClassPathResource resource = new ClassPathResource(path);
try (
InputStream inputStream = resource.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream))) {
String line;
while ((line = bufferedReader.readLine()) != null) {
resultBuilder.append(line);
}
}
return resultBuilder.toString();
}
Below code works with Spring boot(kotlin):
val authReader = InputStreamReader(javaClass.getResourceAsStream("/file1.json"))
If you wanna read as a file, I believe there still is a similar solution:
ClassLoader classLoader = getClass().getClassLoader();
File file = new File(classLoader.getResource("file/test.xml").getFile());
I would like to read a resource from within my jar like so:
File file;
file = new File(getClass().getResource("/file.txt").toURI());
BufferedReader reader = new BufferedReader(new FileReader(file));
//Read the file
and it works fine when running it in Eclipse, but if I export it to a jar, and then run it, there is an IllegalArgumentException:
Exception in thread "Thread-2"
java.lang.IllegalArgumentException: URI is not hierarchical
and I really don't know why but with some testing I found if I change
file = new File(getClass().getResource("/file.txt").toURI());
to
file = new File(getClass().getResource("/folder/file.txt").toURI());
then it works the opposite (it works in jar but not eclipse).
I'm using Eclipse and the folder with my file is in a class folder.
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
To access a file in a jar you have two options:
Place the file in directory structure matching your package name (after extracting .jar file, it should be in the same directory as .class file), then access it using getClass().getResourceAsStream("file.txt")
Place the file at the root (after extracting .jar file, it should be in the root), then access it using Thread.currentThread().getContextClassLoader().getResourceAsStream("file.txt")
The first option may not work when jar is used as a plugin.
I had this problem before and I made fallback way for loading. Basically first way work within .jar file and second way works within eclipse or other IDE.
public class MyClass {
public static InputStream accessFile() {
String resource = "my-file-located-in-resources.txt";
// this is the path within the jar file
InputStream input = MyClass.class.getResourceAsStream("/resources/" + resource);
if (input == null) {
// this is how we load file within editor (eg eclipse)
input = MyClass.class.getClassLoader().getResourceAsStream(resource);
}
return input;
}
}
Up until now (December 2017), this is the only solution I found which works both inside and outside the IDE.
Use PathMatchingResourcePatternResolver
Note: it works also in spring-boot
In this example I'm reading some files located in src/main/resources/my_folder:
try {
// Get all the files under this inner resource folder: my_folder
String scannedPackage = "my_folder/*";
PathMatchingResourcePatternResolver scanner = new PathMatchingResourcePatternResolver();
Resource[] resources = scanner.getResources(scannedPackage);
if (resources == null || resources.length == 0)
log.warn("Warning: could not find any resources in this scanned package: " + scannedPackage);
else {
for (Resource resource : resources) {
log.info(resource.getFilename());
// Read the file content (I used BufferedReader, but there are other solutions for that):
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(resource.getInputStream()));
String line = null;
while ((line = bufferedReader.readLine()) != null) {
// ...
// ...
}
bufferedReader.close();
}
}
} catch (Exception e) {
throw new Exception("Failed to read the resources folder: " + e.getMessage(), e);
}
The problem is that certain third party libraries require file pathnames rather than input streams. Most of the answers don't address this issue.
In this case, one workaround is to copy the resource contents into a temporary file. The following example uses jUnit's TemporaryFolder.
private List<String> decomposePath(String path){
List<String> reversed = Lists.newArrayList();
File currFile = new File(path);
while(currFile != null){
reversed.add(currFile.getName());
currFile = currFile.getParentFile();
}
return Lists.reverse(reversed);
}
private String writeResourceToFile(String resourceName) throws IOException {
ClassLoader loader = getClass().getClassLoader();
InputStream configStream = loader.getResourceAsStream(resourceName);
List<String> pathComponents = decomposePath(resourceName);
folder.newFolder(pathComponents.subList(0, pathComponents.size() - 1).toArray(new String[0]));
File tmpFile = folder.newFile(resourceName);
Files.copy(configStream, tmpFile.toPath(), REPLACE_EXISTING);
return tmpFile.getAbsolutePath();
}
In my case I finally made it with
import java.lang.Thread;
import java.io.BufferedReader;
import java.io.InputStreamReader;
final BufferedReader in = new BufferedReader(new InputStreamReader(
Thread.currentThread().getContextClassLoader().getResourceAsStream("file.txt"))
); // no initial slash in file.txt
Make sure that you work with the correct separator. I replaced all / in a relative path with a File.separator. This worked fine in the IDE, however did not work in the build JAR.
I have found a fix
BufferedReader br = new BufferedReader(new InputStreamReader(Main.class.getResourceAsStream(path)));
Replace "Main" with the java class you coded it in. replace "path" with the path within the jar file.
for example, if you put State1.txt in the package com.issac.state, then type the path as "/com/issac/state/State1" if you run Linux or Mac. If you run Windows then type the path as "\com\issac\state\State1". Don't add the .txt extension to the file unless the File not found exception occurs.
This code works both in Eclipse and in Exported Runnable JAR
private String writeResourceToFile(String resourceName) throws IOException {
File outFile = new File(certPath + File.separator + resourceName);
if (outFile.isFile())
return outFile.getAbsolutePath();
InputStream resourceStream = null;
// Java: In caso di JAR dentro il JAR applicativo
URLClassLoader urlClassLoader = (URLClassLoader)Cypher.class.getClassLoader();
URL url = urlClassLoader.findResource(resourceName);
if (url != null) {
URLConnection conn = url.openConnection();
if (conn != null) {
resourceStream = conn.getInputStream();
}
}
if (resourceStream != null) {
Files.copy(resourceStream, outFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
return outFile.getAbsolutePath();
} else {
System.out.println("Embedded Resource " + resourceName + " not found.");
}
return "";
}
finally i solved errors:
String input_path = "resources\\file.txt";
input_path = input_path.replace("\\", "/"); // doesn't work with back slash
URL file_url = getClass().getClassLoader().getResource(input_path);
String file_path = new URI(file_url.toString().replace(" ","%20")).getSchemeSpecificPart();
InputStream file_inputStream = file_url.openStream();
You can use class loader which will read from classpath as ROOT path (without "/" in the beginning)
InputStream in = getClass().getClassLoader().getResourceAsStream("file.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
For some reason classLoader.getResource() always returned null when I deployed the web application to WildFly 14. getting classLoader from getClass().getClassLoader() or Thread.currentThread().getContextClassLoader() returns null.
getClass().getClassLoader() API doc says,
"Returns the class loader for the class. Some implementations may use null to represent the bootstrap class loader. This method will return null in such implementations if this class was loaded by the bootstrap class loader."
may be if you are using WildFly and yours web application try this
request.getServletContext().getResource() returned the resource url. Here request is an object of ServletRequest.
If you are using spring, then you can use the the following method to read file from src/main/resources:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import org.springframework.core.io.ClassPathResource;
public String readFileToString(String path) throws IOException {
StringBuilder resultBuilder = new StringBuilder("");
ClassPathResource resource = new ClassPathResource(path);
try (
InputStream inputStream = resource.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream))) {
String line;
while ((line = bufferedReader.readLine()) != null) {
resultBuilder.append(line);
}
}
return resultBuilder.toString();
}
Below code works with Spring boot(kotlin):
val authReader = InputStreamReader(javaClass.getResourceAsStream("/file1.json"))
If you wanna read as a file, I believe there still is a similar solution:
ClassLoader classLoader = getClass().getClassLoader();
File file = new File(classLoader.getResource("file/test.xml").getFile());
I would like to read a resource from within my jar like so:
File file;
file = new File(getClass().getResource("/file.txt").toURI());
BufferedReader reader = new BufferedReader(new FileReader(file));
//Read the file
and it works fine when running it in Eclipse, but if I export it to a jar, and then run it, there is an IllegalArgumentException:
Exception in thread "Thread-2"
java.lang.IllegalArgumentException: URI is not hierarchical
and I really don't know why but with some testing I found if I change
file = new File(getClass().getResource("/file.txt").toURI());
to
file = new File(getClass().getResource("/folder/file.txt").toURI());
then it works the opposite (it works in jar but not eclipse).
I'm using Eclipse and the folder with my file is in a class folder.
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
To access a file in a jar you have two options:
Place the file in directory structure matching your package name (after extracting .jar file, it should be in the same directory as .class file), then access it using getClass().getResourceAsStream("file.txt")
Place the file at the root (after extracting .jar file, it should be in the root), then access it using Thread.currentThread().getContextClassLoader().getResourceAsStream("file.txt")
The first option may not work when jar is used as a plugin.
I had this problem before and I made fallback way for loading. Basically first way work within .jar file and second way works within eclipse or other IDE.
public class MyClass {
public static InputStream accessFile() {
String resource = "my-file-located-in-resources.txt";
// this is the path within the jar file
InputStream input = MyClass.class.getResourceAsStream("/resources/" + resource);
if (input == null) {
// this is how we load file within editor (eg eclipse)
input = MyClass.class.getClassLoader().getResourceAsStream(resource);
}
return input;
}
}
Up until now (December 2017), this is the only solution I found which works both inside and outside the IDE.
Use PathMatchingResourcePatternResolver
Note: it works also in spring-boot
In this example I'm reading some files located in src/main/resources/my_folder:
try {
// Get all the files under this inner resource folder: my_folder
String scannedPackage = "my_folder/*";
PathMatchingResourcePatternResolver scanner = new PathMatchingResourcePatternResolver();
Resource[] resources = scanner.getResources(scannedPackage);
if (resources == null || resources.length == 0)
log.warn("Warning: could not find any resources in this scanned package: " + scannedPackage);
else {
for (Resource resource : resources) {
log.info(resource.getFilename());
// Read the file content (I used BufferedReader, but there are other solutions for that):
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(resource.getInputStream()));
String line = null;
while ((line = bufferedReader.readLine()) != null) {
// ...
// ...
}
bufferedReader.close();
}
}
} catch (Exception e) {
throw new Exception("Failed to read the resources folder: " + e.getMessage(), e);
}
The problem is that certain third party libraries require file pathnames rather than input streams. Most of the answers don't address this issue.
In this case, one workaround is to copy the resource contents into a temporary file. The following example uses jUnit's TemporaryFolder.
private List<String> decomposePath(String path){
List<String> reversed = Lists.newArrayList();
File currFile = new File(path);
while(currFile != null){
reversed.add(currFile.getName());
currFile = currFile.getParentFile();
}
return Lists.reverse(reversed);
}
private String writeResourceToFile(String resourceName) throws IOException {
ClassLoader loader = getClass().getClassLoader();
InputStream configStream = loader.getResourceAsStream(resourceName);
List<String> pathComponents = decomposePath(resourceName);
folder.newFolder(pathComponents.subList(0, pathComponents.size() - 1).toArray(new String[0]));
File tmpFile = folder.newFile(resourceName);
Files.copy(configStream, tmpFile.toPath(), REPLACE_EXISTING);
return tmpFile.getAbsolutePath();
}
In my case I finally made it with
import java.lang.Thread;
import java.io.BufferedReader;
import java.io.InputStreamReader;
final BufferedReader in = new BufferedReader(new InputStreamReader(
Thread.currentThread().getContextClassLoader().getResourceAsStream("file.txt"))
); // no initial slash in file.txt
Make sure that you work with the correct separator. I replaced all / in a relative path with a File.separator. This worked fine in the IDE, however did not work in the build JAR.
I have found a fix
BufferedReader br = new BufferedReader(new InputStreamReader(Main.class.getResourceAsStream(path)));
Replace "Main" with the java class you coded it in. replace "path" with the path within the jar file.
for example, if you put State1.txt in the package com.issac.state, then type the path as "/com/issac/state/State1" if you run Linux or Mac. If you run Windows then type the path as "\com\issac\state\State1". Don't add the .txt extension to the file unless the File not found exception occurs.
This code works both in Eclipse and in Exported Runnable JAR
private String writeResourceToFile(String resourceName) throws IOException {
File outFile = new File(certPath + File.separator + resourceName);
if (outFile.isFile())
return outFile.getAbsolutePath();
InputStream resourceStream = null;
// Java: In caso di JAR dentro il JAR applicativo
URLClassLoader urlClassLoader = (URLClassLoader)Cypher.class.getClassLoader();
URL url = urlClassLoader.findResource(resourceName);
if (url != null) {
URLConnection conn = url.openConnection();
if (conn != null) {
resourceStream = conn.getInputStream();
}
}
if (resourceStream != null) {
Files.copy(resourceStream, outFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
return outFile.getAbsolutePath();
} else {
System.out.println("Embedded Resource " + resourceName + " not found.");
}
return "";
}
finally i solved errors:
String input_path = "resources\\file.txt";
input_path = input_path.replace("\\", "/"); // doesn't work with back slash
URL file_url = getClass().getClassLoader().getResource(input_path);
String file_path = new URI(file_url.toString().replace(" ","%20")).getSchemeSpecificPart();
InputStream file_inputStream = file_url.openStream();
You can use class loader which will read from classpath as ROOT path (without "/" in the beginning)
InputStream in = getClass().getClassLoader().getResourceAsStream("file.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
For some reason classLoader.getResource() always returned null when I deployed the web application to WildFly 14. getting classLoader from getClass().getClassLoader() or Thread.currentThread().getContextClassLoader() returns null.
getClass().getClassLoader() API doc says,
"Returns the class loader for the class. Some implementations may use null to represent the bootstrap class loader. This method will return null in such implementations if this class was loaded by the bootstrap class loader."
may be if you are using WildFly and yours web application try this
request.getServletContext().getResource() returned the resource url. Here request is an object of ServletRequest.
If you are using spring, then you can use the the following method to read file from src/main/resources:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import org.springframework.core.io.ClassPathResource;
public String readFileToString(String path) throws IOException {
StringBuilder resultBuilder = new StringBuilder("");
ClassPathResource resource = new ClassPathResource(path);
try (
InputStream inputStream = resource.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream))) {
String line;
while ((line = bufferedReader.readLine()) != null) {
resultBuilder.append(line);
}
}
return resultBuilder.toString();
}
Below code works with Spring boot(kotlin):
val authReader = InputStreamReader(javaClass.getResourceAsStream("/file1.json"))
If you wanna read as a file, I believe there still is a similar solution:
ClassLoader classLoader = getClass().getClassLoader();
File file = new File(classLoader.getResource("file/test.xml").getFile());
I would like to read a resource from within my jar like so:
File file;
file = new File(getClass().getResource("/file.txt").toURI());
BufferedReader reader = new BufferedReader(new FileReader(file));
//Read the file
and it works fine when running it in Eclipse, but if I export it to a jar, and then run it, there is an IllegalArgumentException:
Exception in thread "Thread-2"
java.lang.IllegalArgumentException: URI is not hierarchical
and I really don't know why but with some testing I found if I change
file = new File(getClass().getResource("/file.txt").toURI());
to
file = new File(getClass().getResource("/folder/file.txt").toURI());
then it works the opposite (it works in jar but not eclipse).
I'm using Eclipse and the folder with my file is in a class folder.
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
To access a file in a jar you have two options:
Place the file in directory structure matching your package name (after extracting .jar file, it should be in the same directory as .class file), then access it using getClass().getResourceAsStream("file.txt")
Place the file at the root (after extracting .jar file, it should be in the root), then access it using Thread.currentThread().getContextClassLoader().getResourceAsStream("file.txt")
The first option may not work when jar is used as a plugin.
I had this problem before and I made fallback way for loading. Basically first way work within .jar file and second way works within eclipse or other IDE.
public class MyClass {
public static InputStream accessFile() {
String resource = "my-file-located-in-resources.txt";
// this is the path within the jar file
InputStream input = MyClass.class.getResourceAsStream("/resources/" + resource);
if (input == null) {
// this is how we load file within editor (eg eclipse)
input = MyClass.class.getClassLoader().getResourceAsStream(resource);
}
return input;
}
}
Up until now (December 2017), this is the only solution I found which works both inside and outside the IDE.
Use PathMatchingResourcePatternResolver
Note: it works also in spring-boot
In this example I'm reading some files located in src/main/resources/my_folder:
try {
// Get all the files under this inner resource folder: my_folder
String scannedPackage = "my_folder/*";
PathMatchingResourcePatternResolver scanner = new PathMatchingResourcePatternResolver();
Resource[] resources = scanner.getResources(scannedPackage);
if (resources == null || resources.length == 0)
log.warn("Warning: could not find any resources in this scanned package: " + scannedPackage);
else {
for (Resource resource : resources) {
log.info(resource.getFilename());
// Read the file content (I used BufferedReader, but there are other solutions for that):
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(resource.getInputStream()));
String line = null;
while ((line = bufferedReader.readLine()) != null) {
// ...
// ...
}
bufferedReader.close();
}
}
} catch (Exception e) {
throw new Exception("Failed to read the resources folder: " + e.getMessage(), e);
}
The problem is that certain third party libraries require file pathnames rather than input streams. Most of the answers don't address this issue.
In this case, one workaround is to copy the resource contents into a temporary file. The following example uses jUnit's TemporaryFolder.
private List<String> decomposePath(String path){
List<String> reversed = Lists.newArrayList();
File currFile = new File(path);
while(currFile != null){
reversed.add(currFile.getName());
currFile = currFile.getParentFile();
}
return Lists.reverse(reversed);
}
private String writeResourceToFile(String resourceName) throws IOException {
ClassLoader loader = getClass().getClassLoader();
InputStream configStream = loader.getResourceAsStream(resourceName);
List<String> pathComponents = decomposePath(resourceName);
folder.newFolder(pathComponents.subList(0, pathComponents.size() - 1).toArray(new String[0]));
File tmpFile = folder.newFile(resourceName);
Files.copy(configStream, tmpFile.toPath(), REPLACE_EXISTING);
return tmpFile.getAbsolutePath();
}
In my case I finally made it with
import java.lang.Thread;
import java.io.BufferedReader;
import java.io.InputStreamReader;
final BufferedReader in = new BufferedReader(new InputStreamReader(
Thread.currentThread().getContextClassLoader().getResourceAsStream("file.txt"))
); // no initial slash in file.txt
Make sure that you work with the correct separator. I replaced all / in a relative path with a File.separator. This worked fine in the IDE, however did not work in the build JAR.
I have found a fix
BufferedReader br = new BufferedReader(new InputStreamReader(Main.class.getResourceAsStream(path)));
Replace "Main" with the java class you coded it in. replace "path" with the path within the jar file.
for example, if you put State1.txt in the package com.issac.state, then type the path as "/com/issac/state/State1" if you run Linux or Mac. If you run Windows then type the path as "\com\issac\state\State1". Don't add the .txt extension to the file unless the File not found exception occurs.
This code works both in Eclipse and in Exported Runnable JAR
private String writeResourceToFile(String resourceName) throws IOException {
File outFile = new File(certPath + File.separator + resourceName);
if (outFile.isFile())
return outFile.getAbsolutePath();
InputStream resourceStream = null;
// Java: In caso di JAR dentro il JAR applicativo
URLClassLoader urlClassLoader = (URLClassLoader)Cypher.class.getClassLoader();
URL url = urlClassLoader.findResource(resourceName);
if (url != null) {
URLConnection conn = url.openConnection();
if (conn != null) {
resourceStream = conn.getInputStream();
}
}
if (resourceStream != null) {
Files.copy(resourceStream, outFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
return outFile.getAbsolutePath();
} else {
System.out.println("Embedded Resource " + resourceName + " not found.");
}
return "";
}
finally i solved errors:
String input_path = "resources\\file.txt";
input_path = input_path.replace("\\", "/"); // doesn't work with back slash
URL file_url = getClass().getClassLoader().getResource(input_path);
String file_path = new URI(file_url.toString().replace(" ","%20")).getSchemeSpecificPart();
InputStream file_inputStream = file_url.openStream();
You can use class loader which will read from classpath as ROOT path (without "/" in the beginning)
InputStream in = getClass().getClassLoader().getResourceAsStream("file.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
For some reason classLoader.getResource() always returned null when I deployed the web application to WildFly 14. getting classLoader from getClass().getClassLoader() or Thread.currentThread().getContextClassLoader() returns null.
getClass().getClassLoader() API doc says,
"Returns the class loader for the class. Some implementations may use null to represent the bootstrap class loader. This method will return null in such implementations if this class was loaded by the bootstrap class loader."
may be if you are using WildFly and yours web application try this
request.getServletContext().getResource() returned the resource url. Here request is an object of ServletRequest.
If you are using spring, then you can use the the following method to read file from src/main/resources:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import org.springframework.core.io.ClassPathResource;
public String readFileToString(String path) throws IOException {
StringBuilder resultBuilder = new StringBuilder("");
ClassPathResource resource = new ClassPathResource(path);
try (
InputStream inputStream = resource.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream))) {
String line;
while ((line = bufferedReader.readLine()) != null) {
resultBuilder.append(line);
}
}
return resultBuilder.toString();
}
Below code works with Spring boot(kotlin):
val authReader = InputStreamReader(javaClass.getResourceAsStream("/file1.json"))
If you wanna read as a file, I believe there still is a similar solution:
ClassLoader classLoader = getClass().getClassLoader();
File file = new File(classLoader.getResource("file/test.xml").getFile());
My project has the following structure:
/src/main/java/
/src/main/resources/
/src/test/java/
/src/test/resources/
I have a file in /src/test/resources/test.csv and I want to load the file from a unit test in /src/test/java/MyTest.java
I have this code which didn't work. It complains "No such file or directory".
BufferedReader br = new BufferedReader (new FileReader(test.csv))
I also tried this
InputStream is = (InputStream) MyTest.class.getResourcesAsStream(test.csv))
This also doesn't work. It returns null. I am using Maven to build my project.
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: ClassLoaderUtil1 (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.
Try:
InputStream is = MyTest.class.getResourceAsStream("/test.csv");
IIRC getResourceAsStream() by default is relative to the class's package.
As #Terran noted, don't forget to add the / at the starting of the filename
Try following codes on Spring project
ClassPathResource resource = new ClassPathResource("fileName");
InputStream inputStream = resource.getInputStream();
Or on non spring project
ClassLoader classLoader = getClass().getClassLoader();
File file = new File(classLoader.getResource("fileName").getFile());
InputStream inputStream = new FileInputStream(file);
Here is one quick solution with the use of Guava:
import com.google.common.base.Charsets;
import com.google.common.io.Resources;
public String readResource(final String fileName, Charset charset) throws IOException {
return Resources.toString(Resources.getResource(fileName), charset);
}
Usage:
String fixture = this.readResource("filename.txt", Charsets.UTF_8)
Non spring project:
String filePath = Objects.requireNonNull(getClass().getClassLoader().getResource("any.json")).getPath();
Stream<String> lines = Files.lines(Paths.get(filePath));
Or
String filePath = Objects.requireNonNull(getClass().getClassLoader().getResource("any.json")).getPath();
InputStream in = new FileInputStream(filePath);
For spring projects, you can also use one line code to get any file under resources folder:
File file = ResourceUtils.getFile(ResourceUtils.CLASSPATH_URL_PREFIX + "any.json");
String content = new String(Files.readAllBytes(file.toPath()));
For java after 1.7
List<String> lines = Files.readAllLines(Paths.get(getClass().getResource("test.csv").toURI()));
Alternatively you can use Spring utils if you are in Spring echosystem
final val file = ResourceUtils.getFile("classpath:json/abcd.json");
To get to more behind the scene, check out following blog
https://todzhang.com/blogs/tech/en/save_resources_to_files
I faced the same issue.
The file was not found by a class loader, which means it was not packed into the artifact (jar). You need to build the project. For example, with maven:
mvn clean package
So the files you added to resources folder will get into maven build and become available to the application.
I would like to keep my answer: it does not explain how to read a file (other answers do explain that), it answers why InputStream or resource was null. Similar answer is here.
ClassLoader loader = Thread.currentThread().getContextClassLoader();
InputStream is = loader.getResourceAsStream("test.csv");
If you use context ClassLoader to find a resource then definitely it will cost application performance.
Now I am illustrating the source code for reading a font from maven created resources directory,
scr/main/resources/calibril.ttf
Font getCalibriLightFont(int fontSize){
Font font = null;
try{
URL fontURL = OneMethod.class.getResource("/calibril.ttf");
InputStream fontStream = fontURL.openStream();
font = new Font(Font.createFont(Font.TRUETYPE_FONT, fontStream).getFamily(), Font.PLAIN, fontSize);
fontStream.close();
}catch(IOException | FontFormatException ief){
font = new Font("Arial", Font.PLAIN, fontSize);
ief.printStackTrace();
}
return font;
}
It worked for me and hope that the entire source code will also help you, Enjoy!
Import the following:
import java.io.IOException;
import java.io.FileNotFoundException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.InputStream;
import java.util.ArrayList;
The following method returns a file in an ArrayList of Strings:
public ArrayList<String> loadFile(String filename){
ArrayList<String> lines = new ArrayList<String>();
try{
ClassLoader classloader = Thread.currentThread().getContextClassLoader();
InputStream inputStream = classloader.getResourceAsStream(filename);
InputStreamReader streamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
BufferedReader reader = new BufferedReader(streamReader);
for (String line; (line = reader.readLine()) != null;) {
lines.add(line);
}
}catch(FileNotFoundException fnfe){
// process errors
}catch(IOException ioe){
// process errors
}
return lines;
}
getResource() was working fine with the resources files placed in src/main/resources only. To get a file which is at the path other than src/main/resources say src/test/java you need to create it exlicitly.
the following example may help you
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
public class Main {
public static void main(String[] args) throws URISyntaxException, IOException {
URL location = Main.class.getProtectionDomain().getCodeSource().getLocation();
BufferedReader br = new BufferedReader(new FileReader(location.getPath().toString().replace("/target/classes/", "/src/test/java/youfilename.txt")));
}
}
You can use the com.google.common.io.Resources.getResource to read the url of file and then get the file content using java.nio.file.Files to read the content of file.
URL urlPath = Resources.getResource("src/main/resource");
List<String> multilineContent= Files.readAllLines(Paths.get(urlPath.toURI()));
if you are loading file in static method then
ClassLoader classLoader = getClass().getClassLoader();
this might give you an error.
You can try this
e.g. file you want to load from resources is resources >> Images >> Test.gif
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
Resource resource = new ClassPathResource("Images/Test.gif");
File file = resource.getFile();
To read the files from src/resources folder then try this :
DataSource fds = new FileDataSource(getFileHandle("images/sample.jpeg"));
public static File getFileHandle(String fileName){
return new File(YourClassName.class.getClassLoader().getResource(fileName).getFile());
}
in case of non static reference:
return new File(getClass().getClassLoader().getResource(fileName).getFile());
Does the code work when not running the Maven-build jar, for example when running from your IDE? If so, make sure the file is actually included in the jar. The resources folder should be included in the pom file, in <build><resources>.
The following class can be used to load a resource from the classpath and also receive a fitting error message in case there's a problem with the given filePath.
import java.io.InputStream;
import java.nio.file.NoSuchFileException;
public class ResourceLoader
{
private String filePath;
public ResourceLoader(String filePath)
{
this.filePath = filePath;
if(filePath.startsWith("/"))
{
throw new IllegalArgumentException("Relative paths may not have a leading slash!");
}
}
public InputStream getResource() throws NoSuchFileException
{
ClassLoader classLoader = this.getClass().getClassLoader();
InputStream inputStream = classLoader.getResourceAsStream(filePath);
if(inputStream == null)
{
throw new NoSuchFileException("Resource file not found. Note that the current directory is the source folder!");
}
return inputStream;
}
}
this.getClass().getClassLoader().getResource("filename").getPath()
My file in the test folder could not be found even though I followed the answers. It got resolved by rebuilding the project. It seems IntelliJ did not recognize the new file automatically. Pretty nasty to find out.
I got it work on both running jar and in IDE by writing as
InputStream schemaStream =
ProductUtil.class.getClassLoader().getResourceAsStream(jsonSchemaPath);
byte[] buffer = new byte[schemaStream.available()];
schemaStream.read(buffer);
File tempFile = File.createTempFile("com/package/schema/testSchema", "json");
tempFile.deleteOnExit();
FileOutputStream out = new FileOutputStream(tempFile);
out.write(buffer);
This worked pretty fine for me :
InputStream in = getClass().getResourceAsStream("/main/resources/xxx.xxx");
InputStreamReader streamReader = new InputStreamReader(in, StandardCharsets.UTF_8);
BufferedReader reader = new BufferedReader(streamReader);
String content = "";
for (String line; (line = reader.readLine()) != null;) {
content += line;
}
I get it to work without any reference to "class" or "ClassLoader".
Let's say we have three scenarios with the location of the file 'example.file' and your working directory (where your app executes) is home/mydocuments/program/projects/myapp:
a)A sub folder descendant to the working directory:
myapp/res/files/example.file
b)A sub folder not descendant to the working directory:
projects/files/example.file
b2)Another sub folder not descendant to the working directory:
program/files/example.file
c)A root folder:
home/mydocuments/files/example.file (Linux; in Windows replace home/ with C:)
1) Get the right path:
a)String path = "res/files/example.file";
b)String path = "../projects/files/example.file"
b2)String path = "../../program/files/example.file"
c)String path = "/home/mydocuments/files/example.file"
Basically, if it is a root folder, start the path name with a leading slash.
If it is a sub folder, no slash must be before the path name. If the sub folder is not descendant to the working directory you have to cd to it using "../". This tells the system to go up one folder.
2) Create a File object by passing the right path:
File file = new File(path);
3) You are now good to go:
BufferedReader br = new BufferedReader(new FileReader(file));