23

I'm looking for a way to replace a string in a file without reading the whole file into memory. Normally I would use a Reader and Writer, i.e. something like the following:

public static void replace(String oldstring, String newstring, File in, File out)
    throws IOException {

    BufferedReader reader = new BufferedReader(new FileReader(in));
    PrintWriter writer = new PrintWriter(new FileWriter(out));
    String line = null;
    while ((line = reader.readLine()) != null)
        writer.println(line.replaceAll(oldstring,newstring));

    // I'm aware of the potential for resource leaks here. Proper resource
    // handling has been omitted in the interest of brevity
    reader.close();
    writer.close();
}

However, I want to do the replacement in-place, and don't think I can have a Reader and Writer open on the same file concurrently. Also, I'm using Java 1.4, so dont't have access to NIO, Scanner, etc.

Thanks, Don

2
  • 1
    Just FYI, you're aware that replaceAll is regex-based, right? If you just want to do straight string literal replacement (as your formal parameter names suggest), you can use the replace(CharSequence, CharSequence) method instead. Commented Jun 30, 2010 at 8:40
  • What about writing into a temp file and then replacing the original? Commented Jun 30, 2010 at 8:40

2 Answers 2

32

"In place" replacing usually isn't possible for files, unless the replacement is exactly the same length as the original. Otherwise the file would need to either grow, thus shuffling all later bytes "to the right", or shrink. The common way of doing this is reading the file, writing the replacement to a temporary file, then replacing the original file with the temporary.

This also has the advantage that the file in question is at all times either in the original state or in the completely replaced state, never in between.

Sign up to request clarification or add additional context in comments.

Comments

2

Replacing something in a file or stream requires a Writer or OutputStream which is capable of deleting and inserting bytes at any position. A replace operation can be split into a delete and an insert operation.

Looking at the API of OutputStream and Writer I can't find suitable methods. One could use OutputStream to write bytes with an offset but this will simply overwrite existing context. So it could work for the special case, that original and replacement have the equal length.

So right now I think, writing the edited lines to a temporary file and replacing the orignal file with the temp file afterwards is still the best solution.

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.