I'm reading the documentation of renameTo(File)
in the File.class
of the Android SDK doc.
We've been using this method for a while in production, still I have been wondering what are the possible things that can go wrong. The documentation says
Renames this file to newPath. This operation is supported for both files and directories.
Many failures are possible. Some of the more likely failures include:
Write permission is required on the directories containing both the source and destination paths.
Search permission is required for all parents of both paths.
Both paths be on the same mount point. On Android, applications are most likely to hit this restriction when attempting to copy between internal storage and an SD card. Note that this method does not throw IOException on failure. Callers must check the return value.
What are other possible reasons why renameTo()
might fail (referring to more likely failures)? Is there a guaranteed state after calling renameTo
? When renameTo()
fails, can I rely on having still my original file? Any other conditions I want to check to uber sure that it works beside the described ones from the docs?
The three that are listed are the more likely failures. Less likely (but possible!) failures include
As Android is based on Linux you can probably rely on these though:
In Android File.renameTo calls Linux rename() (via libcore). You can check POSIX standard for the list of possible failures, it may be slightly different on Linux, but should give you general idea.
Also note this statement:
If the rename() function fails for any reason other than [EIO], any file named by new shall be unaffected.
For the reason that I don't know, it's not possible to use file.rename() to move files between to different mounted directory in Android (like sdcard0 and sdcard1), here is my solution and it work for me:
if(canRename(f1, f2)) {
if(!f1.renameTo(f2)) {
Log.e(TAG, "Error to move new app: " + f1 + " > " + f2);
}
} else {
try {
copy(f1, f2);
f1.delete();
} catch (Exception ex) {
Log.e(TAG, "Error to move new app: " + f1 + " > " + f2);
}
}
private void copy(final File f1, final File f2) throws IOException {
f2.createNewFile();
final RandomAccessFile file1 = new RandomAccessFile(f1, "r");
final RandomAccessFile file2 = new RandomAccessFile(f2, "rw");
file2.getChannel().write(file1.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, f1.length()));
file1.close();
file2.close();
}
private boolean canRename(final File f1, final File f2) {
final String p1 = f1.getAbsolutePath().replaceAll("^(/mnt/|/)", "");
final String p2 = f2.getAbsolutePath().replaceAll("^(/mnt/|/)", "");
return p1.replaceAll("\\/\\w+", "").equals(p2.replaceAll("\\/\\w+", ""));
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With