tags:

views:

79

answers:

2

Hi,

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

+7  A: 

"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.

calmh
+1 For a well explained answer
naikus
+1  A: 

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.

Andreas_D