72

How should I load files into my Java application?

Will
  • 2,123
  • 2
  • 15
  • 15
  • If you are using Maven and if your file contains text, you need to pay attention to the encoding (see here: http://tshikatshikaaa.blogspot.nl/2012/07/maven-how-to-access-filesdata-in.html) – Jérôme Verstrynge Jul 27 '12 at 19:25

7 Answers7

56

The short answer

Use one of these two methods:

For example:

InputStream inputStream = YourClass.class.getResourceAsStream("image.jpg");

--

The long answer

Typically, one would not want to load files using absolute paths. For example, don’t do this if you can help it:

File file = new File("C:\\Users\\Joe\\image.jpg");

This technique is not recommended for at least two reasons. First, it creates a dependency on a particular operating system, which prevents the application from easily moving to another operating system. One of Java’s main benefits is the ability to run the same bytecode on many different platforms. Using an absolute path like this makes the code much less portable.

Second, depending on the relative location of the file, this technique might create an external dependency and limit the application’s mobility. If the file exists outside the application’s current directory, this creates an external dependency and one would have to be aware of the dependency in order to move the application to another machine (error prone).

Instead, use the getResource() methods in the Class class. This makes the application much more portable. It can be moved to different platforms, machines, or directories and still function correctly.

Markus Safar
  • 6,324
  • 5
  • 28
  • 44
Will
  • 2,123
  • 2
  • 15
  • 15
  • 7
    Esp. don't do File(“C:\Users\Joe\image.jpg”) because the \U \J and \i are all escapes and you'll get an error. – Lawrence Dol May 02 '09 at 07:38
  • 1
    Can also use it like this: `getClass().getClassLoader().getResource("image.jpg");` – ktulinho May 31 '13 at 13:45
  • Well it should be pointed out that if you're on Windows NT or newer, you *can* use the / character as a separator. So there's no OS that I know of that has both a JRE and won't understand images/splashimage.png for example. – Haakon Løtveit Jul 01 '17 at 20:44
10

getResource is fine, but using relative paths will work just as well too, as long as you can control where your working directory is (which you usually can).

Furthermore the platform dependence regarding the separator character can be gotten around using File.separator, File.separatorChar, or System.getProperty("file.separator").

Mike Stone
  • 44,224
  • 30
  • 113
  • 140
  • 1
    http://docs.oracle.com/javase/7/docs/api/java/lang/ClassLoader.html#getResource(java.lang.String) says: `The name of a resource is a '/'-separated path name that identifies the resource`. So don't use File.separator. – Vsevolod Golovanov Aug 18 '15 at 11:17
8

What are you loading the files for - configuration or data (like an input file) or as a resource?

  • If as a resource, follow the suggestion and example given by Will and Justin
  • If configuration, then you can use a ResourceBundle or Spring (if your configuration is more complex).
  • If you need to read a file in order to process the data inside, this code snippet may help BufferedReader file = new BufferedReader(new FileReader(filename)) and then read each line of the file using file.readLine(); Don't forget to close the file.
Community
  • 1
  • 1
Vinnie
  • 12,400
  • 15
  • 59
  • 80
3

I haven't had a problem just using Unix-style path separators, even on Windows (though it is good practice to check File.separatorChar).

The technique of using ClassLoader.getResource() is best for read-only resources that are going to be loaded from JAR files. Sometimes, you can programmatically determine the application directory, which is useful for admin-configurable files or server applications. (Of course, user-editable files should be stored somewhere in the System.getProperty("user.home") directory.)

Matthias Braun
  • 32,039
  • 22
  • 142
  • 171
McDowell
  • 107,573
  • 31
  • 204
  • 267
  • 1
    In practice using forward slashes works on every Java platform (and I have used them Windows 2000, XP, Vista, Mobile, CE, Linux, OSX, OS/400). – Lawrence Dol May 02 '09 at 07:41
2
public byte[] loadBinaryFile (String name) {
    try {

        DataInputStream dis = new DataInputStream(new FileInputStream(name));
        byte[] theBytes = new byte[dis.available()];
        dis.read(theBytes, 0, dis.available());
        dis.close();
        return theBytes;
    } catch (IOException ex) {
    }
    return null;
} // ()
cibercitizen1
  • 20,944
  • 16
  • 72
  • 95
  • 4
    This uses the ``available()`` method to a) allocate and b) determine the number of bytes to read from the stream. This should never be done since the method is not supposed to return the total number of bytes in the stream. See [the javadoc](http://docs.oracle.com/javase/6/docs/api/java/io/InputStream.html#available%28%29): "It is never correct to use the return value of this method to allocate a buffer intended to hold all data in this stream." – f1sh Apr 29 '14 at 14:46
1

use docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/ClassLoader.html#getResource(java.lang.String)

0
public static String loadTextFile(File f) {
    try {
        BufferedReader r = new BufferedReader(new FileReader(f));
        StringWriter w = new StringWriter();

        try {
            String line = reader.readLine();
            while (null != line) {
                w.append(line).append("\n");
                line = r.readLine();
            }

            return w.toString();
        } finally {
            r.close();
            w.close();
        }
    } catch (Exception ex) {
        ex.printStackTrace();

        return "";
    }
}