Search code examples
javafilebufferedreader

(java) How to update BufferedReader after making changes to the file


I'm currently making a simple text editor for a University task and with user input, on an already existing file, I'm doing basic manipulations (switching line places or word places).

My program consists of a FileManipulator class, where all the logic is contained, and a GUI class (where main is)

public class FileManipulator {

    File file;//current file
    BufferedReader fileReader; //Reader for the file
    String currentDirectory; //Always verified due to setDirectory() validation

    public FileManipulator() throws IOException{ ...;}

    public void loadFile() throws IOException{
        if(this.fileReader != null) {
            this.fileReader.close();
        }
        this.file = new File(this.currentDirectory);

        //if there isn't a txt file, ask user if he wants to create one
        if(!file.exists()) { //logic for creating a new file}

        //After we are sure a file exists in this directory, we init the fileReader
        this.fileReader = new BufferedReader(new FileReader(this.file));
        this.fileReader.mark(READ_AHEAD_LIMIT);
    }

    public void switchLines(int line1, int line2) throws ArrayIndexOutOfBoundsException, IOException {
        //Logic about switching the lines here

        //Writing to the file
        writeToFile(fileContents);
        
    }

    //Will open a writer, write to the file and close the writer
    private void writeToFile(ArrayList<String> listToPrint) throws IOException{
        StringBuilder tempList = new StringBuilder();
        for (String s : listToPrint) {
            tempList.append(s);
            tempList.append('\n');
        }

        FileWriter fileWriter = new FileWriter(this.file);
        fileWriter.append(tempList);
        fileWriter.close();
        /* In this function, we make changes to the file, however, when using getFileText()
         * the changes written in the file aren't noticed and the old file is returned
         */
    }

   //Problematic function
   public String getFileText() throws IOException{
        fileReader.reset();
        StringBuilder finalText = new StringBuilder();

        String temp;

        while((temp = fileReader.readLine()) != null) {
            finalText.append(temp);
            finalText.append('\n');
        }

        return finalText.toString();
    }

After making a change to the file and saving it, my BufferedReader doesn't update. It still reads the contents before the change.

When I use the loadFile method and reload the same file, the buffered reader is closed and reopened, thus the content of the file is updated however, opening and closing the buffered reader every time I'm using it isn't the most elegant solution.

I've also thought of having an ArrayList of the contents of the file and only updating it upon closing the program, but that would be an unnecessary exercise if I'm missing an easy fix.


Solution

  • BufferedReader just works that way. reset and mark are entirely all-done-in-memory.

    There are many solutions:

    1. Hey, you're already committed to storing the entire thing in memory anyway. Why not represent your text file not as a BufferedReader but as a String or List<String> or whatnot, and have the update code update that, then write it out to disk, and there is no read code except when the app starts? Why use the disk as an in-between?

    2. Use FileChannel, RandomAccessFile, or some other abstraction over files specifically which have better support for actually reading from disk. Note that you need this on-write too: On many OSes, 'write all this to this file from scratch' actually makes a new file and any open file handles are still pointing at the old file which is no longer accessible from the file system.

    3. Just.. close that filereader and open it again, or even set a boolean flag to let the read code know that the write code made changes, and only do it when the flag is 'true' (and then set it to false, of course).