I need to modify specific contents of a file in-place.
I do not want to create a new file and rewrite the old. Also the files are small
Java allows random access and writing to files on disk. However, writing to the middle of a file can only over-write bytes -- i.e. replace specific bytes with other bytes -- and cannot insert data into the middle of a file. To do that you must rewrite everything after the insertion point. Think of the file as an array of characters (char[]
) that happens to reside on a disk. Random-access allows you to do the equivalent of
char[] file = ... // the file on disk
char[] newData = ... // the data to be written
int pos = ... // the position in the file to write to
for (i=0; i<newData.; i++)
{
file[pos+i] = newData[i];
}
To insert data in a file would require the same process as inserting data into an array. All data after the point of insertion would have to be moved to the right to accommodate the inserted data. If you are replacing with a shorter string (i.e. removing bytes) then the data after the edit would have to be shifted left.
Secondly, you state:
I need to modify files that are part of version control and need to modify a read-only version
Read-only means exactly that. If the file is read-only, you cannot modify it in any way, whether you use random access or not.
You also said in a comment:
The new file will not be under source control.I will have to find a way to add it.I am trying to avoid this
If the file is under source control, you are most likely working on a local copy. As long as the updated file has the same name as the original and is in the same directory, it should make no difference if you create a new instance of the file. You merely have to commit the updated version to the source control system.
If, however, you are updating the file within the source control system's repository then you are likely to permanently damage the system.
Java supports random file access, in particular using seek()
.
Have a look at: http://docs.oracle.com/javase/tutorial/essential/io/rafs.html
Assuming you want to be able to manipulate the file content as text, and assuming that the file fits in memory (which you say is a valid assumption), then perhaps you might find the methods in Commons IO FileUtils
useful:
http://commons.apache.org/io/apidocs/org/apache/commons/io/FileUtils.html
For example:
File f = new File("my-file.txt");
List<String> lines = FileUtils.readLines(f, "UTF-8");
List<String> outLines = modify(lines); // Do some line-by-line text processing
FileUtils.writeLines(f, "UTF-8", outLines);
So, you're reading the file content into memory, modifying it in-memory, and then over-writing the original file with the new content from memory. Does that meet your criteria for "in-place"?