I had a problem with renaming a properties file. Java’s
File.renameTo()
always failed and returned false. There was no explanation as to why it failed, so it left me stuck with no idea what to do.
Windows has a different file locking policy to Unix (and everyone else). Under Windows, if a process has a file open no other process can rename, move or delete the file until that process has closed all handles to it. As if that wasn’t bad enough, if you do leave a file open and your code finishes running the file will still be locked after an unknown amount of time. It could be 30 seconds or it could be never. Hurray for windows :(
So you must ensure that the file you are trying to rename is completely closed. My problem turned out to be in the loading and saving of properties files. Almost all the example code you download relating to reading and writing properties is wrong.
Properties.load()
and
Properties.store()
both take file streams. If the stream is still open then the file will be locked.
Most of the examples tell you to load the properties like this:
Properties properties = new Properties();
properties.load(new FileInputStream("filename.properties"));
and save them like this:
Properties properties = new Properties();
properties.store(new FileOutputStream("filename.properties"));
I was under the impression that
store
and
load
closed down the stream after they had done their business, but this is not the case. The streams are left open. So when you use the methods above to create a file and read from a file you are leaving the handle open. What’s worse is that because the
FileInputStream
and
FileOutputStream
are in-line there is no reference available to close the streams down - and you are stuffed!
The correct method of reading from a
Properties
file is:
FileInputStream in = null;
Properties properties = new Properties();
try
{
in = new FileInputStream("file.properties");
properties.load(in);
}
finally
{
if (in != null) in.close();
}
and similarly, writing to a
Properties
file:
FileOutputStream out = null;
Properties properties = new Properties();
try
{
out = new FileOutputStream("file.properties");
properties.store(out);
}
finally
{
if (out != null) out.close();
}
Now, after reading and writing, you have explicitly closed the file and you are free to rename the file without error.