FileUtilities - Fish-In-A-Suit/Conquest GitHub Wiki

This class provides functionality to handle files. Currently, this class contains only one method, which is public static String loadResource(String fileName) throws Exception. This method takes in a path of a file, reads it and returns the full content of that file represented as a String.

First, all of the method-local variables are initialized and declared. I've also added a a start and end measurement in nanoseconds, which is then used to calculate the amount of time it took to read the whole file:

    	System.out.println("[FileUtilities.loadResource]: Loading file " + filePath + "...");
    	double start = System.nanoTime();
    	
        String line = null;
        StringBuilder stringBuilder = new StringBuilder();
        String lineSeparator = System.getProperty("line.separator");

A StringBuilder instance (stringBuilder) is used to add (append) a String read by some sort of Reader to an existing String, while not deleting it's previous contents. It's a way of concetanating different Strings.

Then, to create a connection to and read the while, a try-with-resources statement is used (basically a try statement which declares one or more resources inside parentheses). It ensures that each object specified as resource is closed at the end of the statement by itself, regardless of whether the try statement completes normally or abruptly:

        try (
            InputStream in = Class.forName(FileUtilities.class.getName()).getResourceAsStream(filePath);
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in));
            )
        {

        	while((line = bufferedReader.readLine()) != null) {
        		stringBuilder.append(line);
        		
        		while((line = bufferedReader.readLine()) != null) {
        			stringBuilder.append(lineSeparator);
        			stringBuilder.append(line);
        		}
        	}
        	bufferedReader.close();
        } 

The resources to the try statement are in (an instance of InputStream) and bufferedReader - an instance of BufferedReader, which provides buffering to the types of Readers (ex. FileReader, InputStreamReader). Rather than having to read one byte at a time, BufferedReader can read the whole lines which speeds up IO a lot.

Then, inside the "main" try block, a nested while loop is in place to read through the file. The order of reading the contents of the file goes like this:

  • read the first line
  • insert linebreak
  • read next line
  • // make sure not to insert line break at the end

The condition against which both while loops are checked is whether the end of the file is reached. This value is stored in the variable line (which is also used to store the contents of the lines that have already been read). If the BufferedReader reaches the end of a file, no further Strings are generated, so the value of line will take the value null.

In the non-nested while loop, the first line of the document is appended to the already existing String using a StringBuilder instance: stringBuilder.append(line);. Then, the nested while loop is started. Through every cycle of the loop, it first inserts a line separator (stringBuilder.append(lineSeparator);) and then a new line is added using append(). Note that when the end of the line is read, the last "thing" appended to the String inside which all of the contents of the read file are stored is a valid line with text - no line separators at the end!