Reading a File With a Classpath
The Issue
What if we need to open and read a file and we can't rely on the file path?
The Solution
We can read it from the Java classpath without knowing the file path. We already have been using this technique for the properties files. Now we're going to do this so we can read the file ourselves.
getResourceAsStream()
The method getResourceAsStream()
will give us access to a file on the Java classpath. Here are the steps:
-
Obtain a reference to a
Class
instance. We need that in order to call thegetResourceAsStream()
.this.getClass()
-
Determine the name of the file we want to read. This needs to be placed in a directory that is on Java's classpath. To access it there we need to add a slash to the name.
"/file-name.txt"
-
The
getResourceAsStream()
method returns anInputStream
instance. Now we can put these together as the first line in this code.InputStream inputStream = this.getClass().getResourceAsStream("/file-name.txt");
InputStreamReader
In order to use BufferedReader
and the helpful readLine()
method, we need something with the type of Reader
. The InputStream
that we created above is not a Reader
so we have to make one.
The InputStreamReader
class has a constructor that takes an InputStream
. This is how we use it:
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader
Now we can make a BufferedReader
. We know how to use this to read the lines in a file.
BufferedReader searchTokensReader = new BufferedReader(inputStreamReader);
Exception Handling
We know we'll need a try/catch
block. What exceptions will we need to catch? If we let the compiler tell us, and use the try-with-resources syntax, we'll get this as our full code.
try (
InputStream inputStream = this.getClass().getResourceAsStream("/file-name.txt");
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader searchTokensReader = new BufferedReader(inputStreamReader)) {
readSearchTokens(searchTokensReader);
} catch (IOException inputOutputException) {
inputOutputException.printStackTrace();
} catch (Exception exception) {
exception.printStackTrace();
}
The readSearchTokens()
method needs to read through the file in a loop. Note that each search token is on its own line. You will not use the split()
in this analyzer.
The Search Tokens File Name
Where will our code get the name of the file that contains the search tokens? From the analyzer.properties
file. Instead of a full filepath that we might expect, it will be something like this:
classpath.search.tokens=/search-tokens.txt
The property key of classpath.search.tokens
is required. The name of file is up to you.
Don't forget the /
!!!
The file with the search tokens should be saved to the config/
directory. You need to have one search token per line and eliminate spaces in front of and after the tokens. You also need to filter out blank lines like you've done in the FileAnalysis
class. Here's an example of how the file might look:
Georgiana
Bartholomew
steeple
expressed
tombstone
Blacksmith
nothinghere