Reputation: 14008
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.
Upvotes: 410
Views: 825852
Reputation: 7260
To generically access a file in a resource folder, you should use the method getResourceAsStream()
.
// From non-static context
InputStream is = getClass().getClassLoader().getResourceAsStream("test.txt");
// From static context
InputStream is = MyClass.class.getClassLoader().getResourceAsStream("test.txt");
This approach allows you to access a resource whether your application is being developed, tested or built. In fact, when using build tools like Maven or Gradle, resources are copied from ../src/main/resources
to the root of target/classes
or build/classes
. Basically, the getResourceAsStream()
method grants you to access a resource by class code in a way that is independent of the location of the code.
Alternatively, if you need an instance of java.io.File
, you can employ the getResource()
method to retrieve the resource as a URL
, and create a File
from the resource's path or URI. However, using the URI requires handling the URISyntaxException
.
// From non-static context
File f1 = new File(getClass().getClassLoader().getResource("test.txt").getPath());
File f2 = new File(getClass().getClassLoader().getResource("test.txt").toURI());
// From static context
File f1 = new File(MyClass.class.getClassLoader().getResource("test.txt").getPath());
File f2 = new File(MyClass.class.getClassLoader().getResource("test.txt").toURI());
Instead, if you need an instance of java.nio.file.Path
, you can employ the static method Path.of()
(from JDK 11) to build a Path
with the resource's URI.
// From non-static context
Path p = Path.of(getClass().getClassLoader().getResource("test.txt").toURI());
// From static context
Path p = Path.of(Main.class.getClassLoader().getResource("test.txt").toURI());
Upvotes: 0
Reputation: 59
If you want to get a File object:
File file = new File(this.getClass().getClassLoader().getResource("test.csv").toURI())
Upvotes: 0
Reputation: 42060
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
Upvotes: 370
Reputation: 131
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();
Upvotes: 2
Reputation: 146
For Kotlin I am doing the following:
Import these items:
import android.content.Context
import android.util.Log
import java.io.FileNotFoundException
I created a function like this:
fun loadBook(context: Context) {
val assetManager = context.assets
try {
val inputStream = assetManager?.open("19-Psalms.usfm")
val lineList = mutableListOf<String>()
inputStream?.bufferedReader()?.forEachLine { lineList.add(it) }
lineList.forEach{println("> $it")}
}
catch (e:FileNotFoundException) {
Log.e("FileNotFoundException","File not found")
}
}
Upvotes: 1
Reputation: 1568
For Kotlin:
import java.nio.charset.StandardCharsets
import java.nio.file.Files
import java.nio.file.Paths
val lines = Files.readAllLines(
Paths.get((object {}).javaClass.getResource("videos.txt").toURI()),
StandardCharsets.UTF_8
)
lines // will contain list of lines in a file
Upvotes: 0
Reputation: 1481
I am currently doing it this way.
final String path = "src/test/resources/archivos/B-163.txt";
final Path filePath = Path.of( path );
final String documento = Files.readString( filePath );
log.debug("DOCUMENTO: {}" , document);
I am working with Java 11.
Upvotes: 0
Reputation: 270
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;
}
Upvotes: -1
Reputation: 1787
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);
Upvotes: 73
Reputation: 473
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
Upvotes: 17
Reputation: 13113
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.
Upvotes: 7
Reputation: 1073
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);
Upvotes: 0
Reputation: 3979
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());
Upvotes: 1
Reputation: 11980
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.
Upvotes: 0
Reputation: 1852
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()));
Upvotes: 23
Reputation: 340
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()));
Upvotes: 2
Reputation: 9903
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
Upvotes: 125
Reputation: 11424
this.getClass().getClassLoader().getResource("filename").getPath()
Upvotes: 1
Reputation: 2390
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;
}
Upvotes: 3
Reputation: 4965
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!
Upvotes: 5
Reputation: 26729
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)
Upvotes: 45
Reputation: 1890
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")));
}
}
Upvotes: 1
Reputation: 497
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));
Upvotes: -2
Reputation: 19243
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;
}
}
Upvotes: 0
Reputation: 331
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.
Upvotes: 5
Reputation:
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>
.
Upvotes: 0