I was trying to load a file in a webapp, and I was getting a FileNotFound exception when I used FileInputStream. However, using the same path, I was able to load the file when I did getResourceAsStream().
What is the difference between the two methods, and why does one work while the other doesn’t?
I was trying to load a file in a webapp, and I was getting
Share
The
java.io.Fileand consorts acts on the local disk file system. The root cause of your problem is that relative paths injava.ioare dependent on the current working directory. I.e. the directory from which the JVM (in your case: the webserver’s one) is started. This may for example beC:\Tomcat\binor something entirely different, but thus notC:\Tomcat\webapps\contextnameor whatever you’d expect it to be. In a normal Eclipse project, that would beC:\Eclipse\workspace\projectname. You can learn about the current working directory the following way:However, the working directory is in no way programmatically controllable. You should really prefer using absolute paths in the
FileAPI instead of relative paths. E.g.C:\full\path\to\file.ext.You don’t want to hardcode or guess the absolute path in Java (web)applications. That’s only portability trouble (i.e. it runs in system X, but not in system Y). The normal practice is to place those kind of resources in the classpath, or to add its full path to the classpath (in an IDE like Eclipse that’s the
srcfolder and the "build path" respectively). This way you can grab them with help of theClassLoaderbyClassLoader#getResource()orClassLoader#getResourceAsStream(). It is able to locate files relative to the "root" of the classpath, as you by coincidence figured out. In webapplications (or any other application which uses multiple classloaders) it’s recommend to use theClassLoaderas returned byThread.currentThread().getContextClassLoader()for this so you can look "outside" the webapp context as well.Another alternative in webapps is the
ServletContext#getResource()and its counterpartServletContext#getResourceAsStream(). It is able to access files located in the publicwebfolder of the webapp project, including the/WEB-INFfolder. TheServletContextis available in servlets by the inheritedgetServletContext()method, you can call it as-is.See also: