Is This the Best Way to Rewrite the Content of a File in Java

Is this the best way to rewrite the content of a file in Java?

To overwrite file foo.log with FileOutputStream:

File myFoo = new File("foo.log");
FileOutputStream fooStream = new FileOutputStream(myFoo, false); // true to append
// false to overwrite.
byte[] myBytes = "New Contents\n".getBytes();
fooStream.write(myBytes);
fooStream.close();

or with FileWriter :

File myFoo = new File("foo.log");
FileWriter fooWriter = new FileWriter(myFoo, false); // true to append
// false to overwrite.
fooWriter.write("New Contents\n");
fooWriter.close();

Is there a better way to overwrite file contents?

The short answer: write both and profile.

The longer answer with considerable hand-waving:

Overwriting a file will involve the following system calls:

open
write
close

Creating a new file, deleting the old file, and renaming the new file will involve the following system calls:

open
write
close
unlink
rename

System calls are often the slowest part of programs; in general, reducing system calls is a good way to speed a program. Overwriting the one file will re-use the operating system's internal directory entry data; this will probably also lead to some speed improvements. (They may be difficult to measure in a language with VM overhead...)

Your files are small enough that each write() should be handled atomically, assuming you're updating the entire 1K in a single write. (Since you care about performance, this seems like a safe assumption.) This does mean that other processes should not see partial writes except in the case of catastrophic powerfailures and lossy mount options. (Not common.) The file re-name approach does give consistent files even in the face of multiple writes.

However, 1K files are a pretty inefficient storage mechanism; many filesystems will write files along 4k blocks. If these data blocks exist only in your application it might make sense to write them in containers of some sort, several at a time. (Quake-derived systems do this for reading their maps, textures, and so forth, out of zip files, because giant streaming IO requests are far faster than thousands of smaller IO requests.) Of course, this is harder if your application is writing these files for other applications to work with, but it might still be worth investigating if the files are rarely shared.

How to rewrite one specific line of a text file in java

You will need to rewrite the whole file, except the byte length of the file remains the same after your modification. Since this is not guaranteed to be the case or to find out is too cumbersome here is a simple procedure:

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;

public class Lab1 {

public static void main(String[] args) {
String chromVersion = "myChromeVersion";
try {
Path path = Paths.get("C:\\whatever\\path\\toYourFile.txt");
List<String> lines = Files.readAllLines(path, StandardCharsets.UTF_8);
int lineToModify = 31;
lines.set(lineToModify, lines.get(lineToModify)+ chromVersion);
Files.write(path, lines, StandardCharsets.UTF_8);
} catch (IOException ex) {
ex.printStackTrace();
}
}
}

Note that this is not the best way to go for very large files. But for the small file you have it is not an issue.

How to overwrite existing file?

Pass false as 2nd argument, to set append to false, so that you will overwrite the existing file:

FileOutputStream output = new FileOutputStream("output", false);

Check out the constructor documentation:



Related Topics



Leave a reply



Submit