Java File Input/Output

This page will be updated. For now, it includes the video I create to explain how to ad Input/Output from/to files to an existing file. The project I am using is Connect Four.

Import Files

These are the file that need to be imported for bringing in the needed methods for reading from and writing to files. The io.* line imports several needed libraries for writing to a file, while Scanner is needed for reading from a file. The ArrayList is needed for splitting a line into various components.

import java.io.*;                       // Import needed classes for writing to a file
import java.util.ArrayList;             // Create a list of variable size
import java.util.Optional;
import java.util.Scanner;               // Import needed classes for reading files

Writing to a File

I use PrintWriter to write to a file. Each line needs to have dividers for the fields in a line. I usually either use ‘,’ (comma) or ‘ ‘ (space). In this example I use commas to separate fields. There is a bit of set-up that needs to be done before PrintWriter can be used. I do the write when I plan to exit the program.

    //Handle exiting the program and writing new statistics to file.
    public void handleGameExit(Stage mainStage) {
        File fileIn = new File(fileBack);               // Open created backup file for reading
        File fileOut = new File(fileMain);              // Open main file to save all player stats
        boolean fileHere = true;
        try {
            output = new PrintWriter(fileOut);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        try {
            input = new Scanner(fileIn);
        } catch (FileNotFoundException e) {
            //e.printStackTrace();                      // Keep here for debugging
            fileHere = false;
        }
        while (fileHere && input.hasNext()) {           // If backup file exists, read each line
            output.println(input.nextLine());           // Copy lines to main file
        }
        //printStatistics();
        for (int i = 0 ; i < 2 ; i++) {                 // Now load the two players stats
            output.println(players[i].name + ',' + players[i].games + ',' + players[i].wins
                    + ',' + players[i].losses  + ',' + players[i].ties);
        }
        input.close();
        output.close();
        System.exit(0);
    }

Reading Information from a File and Loading Player Statistics

Knowing how information is stored in the file is key to being able to read the information. Since the information for one player is kept on one line with each element separated by a comma. The first code is the code to separate a line into its elements.

/* The reason I am using a vector here is to allow a variable number of Strings to be returned.
 * A line may have different number of Strings separated by spaces or other delimiters.
 */
    void splitLine(ArrayList<String> splitList, String inString, char delim) {
        int len = inString.length();
        int j = 0, k = 0;
        splitList.clear();
        for (int i = 0; i < len; i++) {
            if (inString.charAt(i) == delim) {
                String elem = inString.substring(j, i);
                System.out.println("Element " + k++ + " is " + elem);
                splitList.add(elem);
                j = i + 1;
            }
            if (i == len - 1) {
                String elem = inString.substring(j);
                System.out.println("Element " + k++ + " is " + elem);
                splitList.add(elem);
            }
        }
    }

The actual read of the file follows. It opens the primary file and looks for the two players’ statistics. If these players have any statistics in the primary file, all other lines are written to a backup file. The found players’ statistics are then loaded into the statistics for the game.

 // initialize players
    private void initPlayers() throws IOException {
        String inLine, name;
        int games = 0, wins = 0, losses = 0, ties = 0;
        ArrayList<String> splitList = new ArrayList<>();
        File fileIn = new File(fileMain);
        File fileOut = new File(fileBack);
        players[0].games = players[1].games = 0;
        players[0].wins = players[1].wins = 0;
        players[0].losses = players[1].losses = 0;
        players[0].ties = players[1].ties = 0;
        if (fileIn.exists()) {
            output = new PrintWriter(fileOut);
            input = new Scanner(fileIn);
            while (input.hasNext()) {
                boolean notFound = true;
                inLine = input.nextLine();
                splitLine(splitList, inLine, ',');
                name = splitList.get(0);
                games = Integer.parseInt(splitList.get(1));
                wins = Integer.parseInt(splitList.get(2));
                losses = Integer.parseInt(splitList.get(3));
                ties = Integer.parseInt(splitList.get(4));
                for (int i = 0; i < 2; i++) {
                    if (name.equals(players[i].name)) {
                        players[i].games = games;
                        players[i].wins = wins;
                        players[i].losses = losses;
                        players[i].ties = ties;
                        notFound = false;
                    }
                }
                if(notFound)  output.println(inLine);
             }
            output.close();
            input.close();
        }
        playerStats.setText(players[0].name + "'s Turn");
    }

Printing Store Statistics

The following code is optional. It includes reading the information from a stored file and, in this case, printing the player statistics to a dialog box.

 // Allow the user to show the current statistics
    public void handlePrintStatistics(Stage mainStage) throws FileNotFoundException {
        File fileIn = new File(fileMain);
        Alert dialog = new Alert(Alert.AlertType.NONE);
        ArrayList<String> splitList = new ArrayList<>();
        dialog.initOwner(mainStage);
        dialog.setTitle("Player Statistics");
        GridPane gridPane = new GridPane();
        gridPane.setHgap(10);
        gridPane.setVgap(10);

        // Set up Text Area
        String output = "Name\tGames\tWins\t Losses\tTies\n";
        if (fileIn.exists()) {
            input = new Scanner(fileIn);
            String inLine;
            while (input.hasNext()) {
                inLine = input.nextLine();
                splitLine(splitList, inLine, ',');
                String name = splitList.get(0);
                int games = Integer.parseInt(splitList.get(1));
                int wins = Integer.parseInt(splitList.get(2));
                int losses = Integer.parseInt(splitList.get(3));
                int ties = Integer.parseInt(splitList.get(4));
                int len = name.length();
                // Statistics are read from the file above, make sure current statistics are shown.
                for (int i = 0 ; i < 2 ; i++) {
                    if (name.equals(players[i].name)) {
                        games = players[i].games;
                        wins = players[i].wins;
                        losses = players[i].losses;
                        ties = players[i].ties;
                    }
                }
                output += name + (len < 5 ? "\t\t" : "\t") + games + "\t\t" + wins + "\t\t"
                        + losses + "\t\t" + ties + "\n";
            }
            input.close();
        }
        TextArea area = new TextArea(output);
        area.setPrefColumnCount(40);
        area.setPrefRowCount(20);
        ButtonType okButton = new ButtonType("OK");
        gridPane.getChildren().add(area);
        dialog.getDialogPane().setContent(gridPane);
        dialog.getButtonTypes().addAll(okButton);
        //dialog.show();

        // Now take care of the buttons
        Optional<ButtonType> result = dialog.showAndWait();
        if (result.get() == okButton) {
            dialog.close();
        }
    }

I would enjoy hearing from you.

This site uses Akismet to reduce spam. Learn how your comment data is processed.