views:

1264

answers:

6

I want to rewrite the contents of a file.

What I have thought of so far is this:

  1. Save the file name
  2. Delete the existing file
  3. Create a new empty file with the same name
  4. Write the desired content to the empty file

Is this the best way? Or is there a more direct way, that is, not having to delete and create files, but simply change the content?

+5  A: 

To overwrite file foo.log:

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

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();

Edit: show examples of both FileOutputStream and FileWriter...

Stobor
Umm, actually outputstreams don't write lines; I should have used FileWriter, or used .write("".getBytes())...
Stobor
Why not modify your post now. :)
Adeel Ansari
@Vinegar: was doing that, just confirming the all method names first... ;-)
Stobor
Your second solution works and seems to be the simplest. Thanks
Ankur
@Ankur: yeah. It depends on whether you're writing strings or binary stuff in bytes as to whether you'd use the OutputStream or the Writer approach.
Stobor
+2  A: 

Unless you're just adding content at the end, it's reasonable to do it that way. If you are appending, try FileWriter with the append constructor.

A slightly better order would be:

  1. Generate new file name (e.g. foo.txt.new)
  2. Write updated content to new file.
  3. Do atomic rename from foo.txt.new to foo.txt

Unfortunately, renameTo is not guaranteed to do atomic rename.

Matthew Flaschen
A: 

See: java.io.RandomAccessFile

You'll want to open a File read-write, so:

RandomAccessFile raf = new RandomAccessFile("filename.txt", "rw");
String tmp;
while (tmp = raf.readLine() != null) {
    // Store String data
}
// do some string conversion
raf.seek(0);
raf.writeChars("newString");
drfloob
I misread the question as the need to rewrite a file, e.g. modify the contents, not replace entirely with new content.
drfloob
Either will solve the problem :)
Ankur
+1  A: 

In the below example, the "false" causes the file to be overwritten, true would cause the opposite.

File file=new File("C:\Path\to\file.txt");
DataOutputStream outstream= new DataOutputStream(new FileOutputStream(file,false));
String body = "new content";
outstream.write(body.getBytes());
outstream.close();
Sev
Curious! whats the benefit of introducing DataOutputSteam?
Adeel Ansari
The size() and writeUTF() methods have been useful to me thus far, so I chose to use that. You can also not convert to bytes before writing the string using DataOutputStream.
Sev
DataInputStream and DataOutputStream are specialized classes for working with a certain kind of binary file; they should not be used on text files. The correct way to read and write text files is with Readers and Writers: FileReader and FileWriter use the platform default encoding, while InputStreamReader and OutputStreamWriter let you specify the encoding (like UTF-8).
Alan Moore
+1  A: 

I would highly recommend using the Apache Common's FileUtil for this. I have found this package invaluable. It's easy to use and equally important it's easy to read/understand when you go back a while later.

//Create some files here
File sourceFile = new File("pathToYourFile");
File fileToCopy = new File("copyPath");

//Sample content
org.apache.commons.io.FileUtils.writeStringToFile(sourceFile, "Sample content");

//Now copy from source to copy, the delete source.
org.apache.commons.io.FileUtils.copyFile(sourceFile, fileToCopy);
org.apache.commons.io.FileUtils.deleteQuietly(sourceFile);

More information can be found at: http://commons.apache.org/io/api-release/org/apache/commons/io/FileUtils.html

jnt30
+1  A: 

There are times when one may want to keep a huge empty file so as to avoid extra cost of the OS allocating space on need basis. This is generally done by databases, Virtual machines and also in batch programs that process and write bulk data. This would improve the performance of the application significantly. In these cases, writing a new file and renaming it would not really help. Instead, the empty file will have to be filled up. That is when one must go for the override mode.

Lakshmi