38

How do I replace a line of text found within a text file?

I have a string such as:

Do the dishes0

And I want to update it with:

Do the dishes1

(and vise versa)

How do I accomplish this?

ActionListener al = new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    JCheckBox checkbox = (JCheckBox) e.getSource();
                    if (checkbox.isSelected()) {
                        System.out.println("Selected");
                        String s = checkbox.getText();
                        replaceSelected(s, "1");
                    } else {
                        System.out.println("Deselected");
                        String s = checkbox.getText();
                        replaceSelected(s, "0");
                    }
                }
            };

public static void replaceSelected(String replaceWith, String type) {

}

By the way, I want to replace ONLY the line that was read. NOT the entire file.

7
  • 9
    Read the ENTIRE file. Change the line. Write the ENTIRE file. Commented Nov 18, 2013 at 4:22
  • I've tried to do this using RandomAccessFile and BufferedReader and BufferedWriters. I really need some code designed for my specific purpose. I seem to be doing something wrong every time I try. Commented Nov 18, 2013 at 4:23
  • Then I suggest posting the code where you're making this effort and let SO help you figure out what you're doing wrong. Commented Nov 18, 2013 at 4:24
  • It's long gone now. As I've said I've tried many different methods. Storing it in a temporary array.. creating a new file.. none of it worked. Commented Nov 18, 2013 at 4:25
  • Well you need to go back to implementing these methods, and when you get stuck, come back here and post that. Commented Nov 18, 2013 at 4:26

8 Answers 8

51

At the bottom, I have a general solution to replace lines in a file. But first, here is the answer to the specific question at hand. Helper function:

public static void replaceSelected(String replaceWith, String type) {
    try {
        // input the file content to the StringBuffer "input"
        BufferedReader file = new BufferedReader(new FileReader("notes.txt"));
        StringBuffer inputBuffer = new StringBuffer();
        String line;

        while ((line = file.readLine()) != null) {
            inputBuffer.append(line);
            inputBuffer.append('\n');
        }
        file.close();
        String inputStr = inputBuffer.toString();

        System.out.println(inputStr); // display the original file for debugging

        // logic to replace lines in the string (could use regex here to be generic)
        if (type.equals("0")) {
            inputStr = inputStr.replace(replaceWith + "1", replaceWith + "0"); 
        } else if (type.equals("1")) {
            inputStr = inputStr.replace(replaceWith + "0", replaceWith + "1");
        }

        // display the new file for debugging
        System.out.println("----------------------------------\n" + inputStr);

        // write the new string with the replaced line OVER the same file
        FileOutputStream fileOut = new FileOutputStream("notes.txt");
        fileOut.write(inputStr.getBytes());
        fileOut.close();

    } catch (Exception e) {
        System.out.println("Problem reading file.");
    }
}

Then call it:

public static void main(String[] args) {
    replaceSelected("Do the dishes", "1");   
}

Original Text File Content:

Do the dishes0
Feed the dog0
Cleaned my room1

Output:

Do the dishes0
Feed the dog0
Cleaned my room1
----------------------------------
Do the dishes1
Feed the dog0
Cleaned my room1

New text file content:

Do the dishes1
Feed the dog0
Cleaned my room1


And as a note, if the text file was:

Do the dishes1
Feed the dog0
Cleaned my room1

and you used the method replaceSelected("Do the dishes", "1");, it would just not change the file.


Since this question is pretty specific, I'll add a more general solution here for future readers (based on the title).

// read file one line at a time
// replace line as you read the file and store updated lines in StringBuffer
// overwrite the file with the new lines
public static void replaceLines() {
    try {
        // input the (modified) file content to the StringBuffer "input"
        BufferedReader file = new BufferedReader(new FileReader("notes.txt"));
        StringBuffer inputBuffer = new StringBuffer();
        String line;

        while ((line = file.readLine()) != null) {
            line = ... // replace the line here
            inputBuffer.append(line);
            inputBuffer.append('\n');
        }
        file.close();

        // write the new string with the replaced line OVER the same file
        FileOutputStream fileOut = new FileOutputStream("notes.txt");
        fileOut.write(inputBuffer.toString().getBytes());
        fileOut.close();

    } catch (Exception e) {
        System.out.println("Problem reading file.");
    }
}
Sign up to request clarification or add additional context in comments.

10 Comments

You need to make sure you close your streams when you're finished with them.
@SammyGuergachi You're right. I always get lazy and don't do that. If you suggest an edit, I'll approve it.
You also should use StringBuilder instead of "while (...) input += line + '\n'" for best practises stackoverflow.com/questions/1532461/…
Consider replacing "String input" with "StringBuilder input" and use it as input.append(line + "\n);". A string is an immutable object while a StringBuilder is not. Therefore every time you modify a String you create a new Object. Once you are done with your data get the string with "input.toString()".
what is type here. I have quite similer situation please have a look . it will help stackoverflow.com/questions/50809375/…
|
50

Since Java 7 this is very easy and intuitive to do.

List<String> fileContent = new ArrayList<>(Files.readAllLines(FILE_PATH, StandardCharsets.UTF_8));

for (int i = 0; i < fileContent.size(); i++) {
    if (fileContent.get(i).equals("old line")) {
        fileContent.set(i, "new line");
        break;
    }
}

Files.write(FILE_TEMP_PATH, fileContent, StandardCharsets.UTF_8);
Files.copy(FILE_TEMP_PATH, FILE_PATH, StandardCopyOption.REPLACE_EXISTING);

Basically you read the whole file to a List, edit the list and finally write the list back to file.

FILE_PATH represents the Path of the file.

8 Comments

Suggestion: Also explain how to it is important to write to a temp file, and then move that file into place over the first file in order to make the change atomic. (And welcome to StackOverflow!)
@rrauenza That is not necessary and would mostly be an overkill. That being said it certainly wouldn't be hard to implement in few lines. If you want to demonstrate that, why not make your own answer (or suggest an edit)?
I don't know Java well enough and you should get credit for the answer. (As a reviewer, I'm asked to make suggestions to improve "first posts.")
I need to refer to java2s.com/Tutorials/Java/java.nio.file/Files/…, as above answer was not complete
Above answer produced an error : The method write(Path, byte[], OpenOption...) in the type Files is not applicable for the arguments (Path, byte[], Charset)
|
4

Sharing the experience with Java Util Stream

import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;    

public static void replaceLine(String filePath, String originalLineText, String newLineText) {
            Path path = Paths.get(filePath);
            // Get all the lines
            try (Stream<String> stream = Files.lines(path, StandardCharsets.UTF_8)) {
                // Do the line replace
                List<String> list = stream.map(line -> line.equals(originalLineText) ? newLineText : line)
                        .collect(Collectors.toList());
                // Write the content back
                Files.write(path, list, StandardCharsets.UTF_8);
            } catch (IOException e) {
                LOG.error("IOException for : " + path, e);
                e.printStackTrace();
            }
        }

Usage

replaceLine("test.txt", "Do the dishes0", "Do the dishes1");

Comments

1

If replacement is of different length:

  1. Read file until you find the string you want to replace.
  2. Read into memory the part after text you want to replace, all of it.
  3. Truncate the file at start of the part you want to replace.
  4. Write replacement.
  5. Write rest of the file from step 2.

If replacement is of same length:

  1. Read file until you find the string you want to replace.
  2. Set file position to start of the part you want to replace.
  3. Write replacement, overwriting part of file.

This is the best you can get, with constraints of your question. However, at least the example in question is replacing string of same length, So the second way should work.

Also be aware: Java strings are Unicode text, while text files are bytes with some encoding. If encoding is UTF8, and your text is not Latin1 (or plain 7-bit ASCII), you have to check length of encoded byte array, not length of Java string.

Comments

1

I was going to answer this question. Then I saw it get marked as a duplicate of this question, after I'd written the code, so I am going to post my solution here.

Keeping in mind that you have to re-write the text file. First I read the entire file, and store it in a string. Then I store each line as a index of a string array, ex line one = array index 0. I then edit the index corresponding to the line that you wish to edit. Once this is done I concatenate all the strings in the array into a single string. Then I write the new string into the file, which writes over the old content. Don't worry about losing your old content as it has been written again with the edit. below is the code I used.

public class App {

public static void main(String[] args) {

    String file = "file.txt";
    String newLineContent = "Hello my name is bob";
    int lineToBeEdited = 3;

    ChangeLineInFile changeFile = new ChangeLineInFile();
    changeFile.changeALineInATextFile(file, newLineContent, lineToBeEdited);



}

}

And the class.

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;

public class ChangeLineInFile {

public void changeALineInATextFile(String fileName, String newLine, int lineNumber) {
        String content = new String();
        String editedContent = new String();
        content = readFile(fileName);
        editedContent = editLineInContent(content, newLine, lineNumber);
        writeToFile(fileName, editedContent);

    }

private static int numberOfLinesInFile(String content) {
    int numberOfLines = 0;
    int index = 0;
    int lastIndex = 0;

    lastIndex = content.length() - 1;

    while (true) {

        if (content.charAt(index) == '\n') {
            numberOfLines++;

        }

        if (index == lastIndex) {
            numberOfLines = numberOfLines + 1;
            break;
        }
        index++;

    }

    return numberOfLines;
}

private static String[] turnFileIntoArrayOfStrings(String content, int lines) {
    String[] array = new String[lines];
    int index = 0;
    int tempInt = 0;
    int startIndext = 0;
    int lastIndex = content.length() - 1;

    while (true) {

        if (content.charAt(index) == '\n') {
            tempInt++;

            String temp2 = new String();
            for (int i = 0; i < index - startIndext; i++) {
                temp2 += content.charAt(startIndext + i);
            }
            startIndext = index;
            array[tempInt - 1] = temp2;

        }

        if (index == lastIndex) {

            tempInt++;

            String temp2 = new String();
            for (int i = 0; i < index - startIndext + 1; i++) {
                temp2 += content.charAt(startIndext + i);
            }
            array[tempInt - 1] = temp2;

            break;
        }
        index++;

    }

    return array;
}

private static String editLineInContent(String content, String newLine, int line) {

    int lineNumber = 0;
    lineNumber = numberOfLinesInFile(content);

    String[] lines = new String[lineNumber];
    lines = turnFileIntoArrayOfStrings(content, lineNumber);

    if (line != 1) {
        lines[line - 1] = "\n" + newLine;
    } else {
        lines[line - 1] = newLine;
    }
    content = new String();

    for (int i = 0; i < lineNumber; i++) {
        content += lines[i];
    }

    return content;
}

private static void writeToFile(String file, String content) {

    try (Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "utf-8"))) {
        writer.write(content);
    } catch (UnsupportedEncodingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

private static String readFile(String filename) {
    String content = null;
    File file = new File(filename);
    FileReader reader = null;
    try {
        reader = new FileReader(file);
        char[] chars = new char[(int) file.length()];
        reader.read(chars);
        content = new String(chars);
        reader.close();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (reader != null) {
            try {
                reader.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
    return content;
}

}

Comments

1
        //Read the file data
        BufferedReader file = new BufferedReader(new FileReader(filepath));
        StringBuffer inputBuffer = new StringBuffer();
        String line;

        while ((line = file.readLine()) != null) {
            inputBuffer.append(line);
            inputBuffer.append('\n');
        }
        file.close();
        String inputStr = inputBuffer.toString();


        // logic to replace lines in the string (could use regex here to be generic)

            inputStr = inputStr.replace(str, " ");
        //'str' is the string need to update in this case it is updating with nothing

        // write the new string with the replaced line OVER the same file
        FileOutputStream fileOut = new FileOutputStream(filer);
        fileOut.write(inputStr.getBytes());
        fileOut.close();

Comments

0

Well you would need to get a file with JFileChooser and then read through the lines of the file using a scanner and the hasNext() function

http://docs.oracle.com/javase/7/docs/api/javax/swing/JFileChooser.html

once you do that you can save the line into a variable and manipulate the contents.

2 Comments

I'll look into this. Thanks. Would you mind posting a quick example of what it would like though all together so I have an idea?
You can find everything you need in the Java Tutorial.
0

just how to replace strings :) as i do first arg will be filename second target string third one the string to be replaced instead of targe

public class ReplaceString{
      public static void main(String[] args)throws Exception {
        if(args.length<3)System.exit(0);
        String targetStr = args[1];
        String altStr = args[2];
        java.io.File file = new java.io.File(args[0]);
        java.util.Scanner scanner = new java.util.Scanner(file);
        StringBuilder buffer = new StringBuilder();
        while(scanner.hasNext()){
          buffer.append(scanner.nextLine().replaceAll(targetStr, altStr));
          if(scanner.hasNext())buffer.append("\n");
        }
        scanner.close();
        java.io.PrintWriter printer = new java.io.PrintWriter(file);
        printer.print(buffer);
        printer.close();
      }
    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.