How do I load a file from resource folder?
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))
InputStream is = (InputStream) MyTest.class.getResourcesAsStream(test.csv))
@SRy it worked (cause this will give absolute path url in return ) however the moment i make jar file it’s not working as its inside a jar and absolute path becomes invalid, is there a way to play with relative path itself
@SRy, somewhere between now and 2013, this seems to have been fixed. I am today able to load root resources without the initial / . However, I do getClass().getClassLoader().getResourceAsStream(filename) . maybe that’s the difference?
21 Answers 21
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 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 >
thx for the answer, could you please explain why we should use this very specific loader but not that of the class ?
great, I’m so stupid that I was using Object.class.getClassLoader(); , from a static context which didn’t work — this suggestion does — well almost, it injects %20 for spaces which gives me a FileNotFoundException
@ycomp Because getResource returns a URL, not a file. The getFile method of java.net.URL does not convert a URL to a file; it just returns the path and query portions of the URL. You shouldn’t even try to convert it to a File; just call openStream and read from that.
The one liner suggested by @prayagupa only works in Java 9 or higher, see stackoverflow.com/questions/54269211/…
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
For those seeking sanity, this post brings you all the way to getting the resource as a String stackoverflow.com/a/35446009/544045
Try following codes on Spring project
ClassPathResource resource = new ClassPathResource("fileName"); InputStream inputStream = resource.getInputStream();
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
String fixture = this.readResource("filename.txt", Charsets.UTF_8)
The docs say that this about the getResource method: ‘getResource(java.lang.String)’ is declared in unstable class ‘com.google.common.io.Resources’ marked with @Beta . Should people really be using methods from an unstable class?
String filePath = Objects.requireNonNull(getClass().getClassLoader().getResource("any.json")).getPath(); Stream lines = Files.lines(Paths.get(filePath));
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 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
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:
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.
Programmers should always be concerned about performance. While premature optimization is certainly to be avoided, knowing the more efficient approach to take is always good. It’s like knowing the difference between LinkedList and ArrayList and when to use one or the other.
@Marvo: Programmers must always be concerned about quality, capabilities and ease of maintenance, performance is at the queue.
Now I am illustrating the source code for reading a font from maven created resources directory,
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 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 loadFile(String filename) < ArrayListlines = new ArrayList(); 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 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)
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 .
When using eclipse and running code from IDE itself. How can we load resources located at «/src/test/resources» in Java code specifically in unit tests. Consider a standard maven project structure.
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;)
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:
BufferedReader br = new BufferedReader(new FileReader(file));
How to read file on Windows and Linux from Java
I have a xml file located in D:\XML\RequestXML and I am reading xml file in this folder from a FileReader . In my program I hard coded the file path /XML/RequestXML/ . This works fine with the windows environment. In windows JBoss is in D:\jbossdistrib\jboss . I created the folder structure in linux /usr/XML/RequestXML/ . And add the xml in to RequestXML folder. JBoss is in /usr/jbossdistrib/jboss/ path. But my application can not find the file specified in /XML/RequestXML/ in linux environment. If I change the file path as /usr/XML/RequestXML/ it works in linux. How can I use the consistent file path in linux and windows both?
public class Controller extends HttpServlet < private String filePath = "/XML/RequestXML/"; protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException < String file = request.getParameter("fileName"); xml = readFile(filePath + file); >private String readFile(String file) < StringBuffer fileData = new StringBuffer(); try < BufferedReader reader = new BufferedReader(new FileReader(file)); char[] buf = new char[1024]; int numRead=0; while((numRead=reader.read(buf)) != -1)< String readData = String.valueOf(buf, 0, numRead); fileData.append(readData); buf = new char[1024]; >reader.close(); > catch (FileNotFoundException e) < logger.fatal("File not found in specifid path "+ file); >catch (IOException e) < logger.fatal("Error while reading the xml file"); >return fileData.toString(); > >
Update My question is how to set the file path without /usr/ which works fine in Windows. If this is not possible, then do I need to use the path as /usr/XML/RequestXML/ in windows environment as well? so I have to create a folder structure like D:\usr\XML\RequestXML in windows.