16

I've googled around for quite a while for this, but all the results point to pre-Java 7 NIO solutions. I've used the NIO stuff to read in files from the a specific place on the file system, and it was so much easier than before (Files.readAllBytes(path)). Now, I'm wanting to read in a file that is packaged in my WAR and on the classpath. We currently do that with code similar to the following:

Input inputStream = this.getClass().getClassLoader().getResourceAsStream(fileName);
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();

/* iterate through the input stream to get all the bytes (no way to reliably find the size of the 
 *     file behind the inputStream (see http://docs.oracle.com/javase/6/docs/api/java/io/InputStream.html#available()))
 */
int byteInt = -1;
try
{
    byteInt = inputStream.read();
    while (byteInt != -1)
    {
        byteStream.write(byteInt);
        byteInt = inputStream.read();
    }

    byteArray = byteStream.toByteArray();
    inputStream.close();
    return byteArray;
}
catch (IOException e)
{
    //...
}

While this works, I was hoping there was an easier/better way to do this with the NIO stuff in Java 7. I'm guessing I'll need to get a Path object that represents this path on the classpath, but I'm not sure how to do that.

I apologize if this is some super easy thing to do. I just cannot figure it out. Thanks for the help.

2
  • 1
    Have you tried YourClass.class.getResourceAsStream(filename);? Commented Feb 4, 2013 at 18:10
  • 1
    Time to update Best answer? Commented Oct 14, 2015 at 15:36

4 Answers 4

30

This works for me.

import java.nio.file.Files;
import java.nio.file.Paths;

// fileName: foo.txt which lives under src/main/resources
public String readFileFromClasspath(final String fileName) throws IOException, URISyntaxException {
    return new String(Files.readAllBytes(
                Paths.get(getClass().getClassLoader()
                        .getResource(fileName)
                        .toURI())));
}
Sign up to request clarification or add additional context in comments.

2 Comments

It doesn't work if you execute this peice of code with command line if foo.txt is under src/main/resources, because calling toURI() from jar:file will give you NullPointerException
You can use utility method which reads directly into String, instead of byte array: Files.readString(Paths.get(getClass().getClassLoader().getResource(fileName).toURI()));
8

A Path represents a file on the file system. It doesn't help to read a resource from the classpath. What you're looking after is a helper method that reads everything fro a stream (more efficiently than how you're doing) and writes it to a byte array. Apache commons-io or Guava can help you with that. For example with Guava:

byte[] array = 
    ByteStreams.toByteArray(this.getClass().getClassLoader().getResourceAsStream(resourceName));

If you don't want to add Guava or commons-io to your dependencies just for that, you can always read their source code and duplicate it to your own helper method.

2 Comments

That is not asynchronous which is one of the primary purposes of NIO.
stream is not closed
3

As far as I understand, what you want is to open a ReadableByteChannel to your resource, so you can use NIO for reading it.

This should be a good start,

// Opens a resource from the current class' defining class loader
InputStream istream = getClass().getResourceAsStream("/filename.txt");

// Create a NIO ReadableByteChannel from the stream
ReadableByteChannel channel = java.nio.channels.Channels.newChannel(istream);

Comments

1

You should look at ClassLoader.getResource(). This returns a URL which represents the resource. If it's local to the file system, it will be a file:// URL. At that point you can strip off the scheme etc., and then you have the file name with which you can do whatever you want.

However, if it's not a file:// path, then you can fall back to the normal InputStream.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.