Accessing Files in a JAR
May 28, 2015
I wanted to have text files in my Java project that I could read and process in a Java program. I wanted this to work both when running code in Eclipse, and when running an executable JAR file of the same code.
I added a marker.txt
file at top of my project inside the src
directory. This will be included at the top level of the JAR file.
We can get hold of the location of this file using the following code:
URI lUri = DatabaseConfigurator.class.getResource("/marker.txt").toURI();
Once we have this, we can work out whether we're in a JAR file or not, and populate the lPath
variable appropriately.
Path lPath; if ("jar".equals(lUri.getScheme())) { // We're running within a jar file if (this.fileSystem == null) { try { // Create a reference to the filesystem this.fileSystem = FileSystems.newFileSystem(lUri, Collections.<String, Object> emptyMap()); } catch (FileSystemAlreadyExistsException lEx) { // Sometimes newFileSystem seems to raise FileSystemAlreadyExistsException - this code gets around this problem. this.fileSystem = FileSystems.getFileSystem(lUri); } } // Get hold of the path to the top level directory of the JAR file lPath = this.fileSystem.getPath("/"); } else { // We're running within eclipse, we'll be in the bin directory. lUri = ThisClass.class.getResource("/").toURI(); // Move to ../src to move out of the bin directory lPath = Paths.get(lUri).getParent().resolve("src"); }
At this point we have lPath
pointing at the top level src
directory, or the top level directory in the JAR file. We can now move to the directory we want to look at.
In this instance pLocation is a string containing something like core/plsql
lPath = lPath.resolve(pLocation);
We can now use FileFinder
(a subclass of SimpleFileVisitor
) to process all the files found within the location specified. This will work both inside Eclipse and inside the JAR file.
FileFinder lFileFinder = new FileFinder(pPassThingsHereToUseWithinTheFileFinder); Files.walkFileTree(lPath, lFileFinder);
The subclass of SimpleFileVisitor
contains an overload of visitFile which is called for each file found and should implement the required processing:
public FileVisitResult visitFile(Path pPath, BasicFileAttributes pAttributes) { ... }