4

I got a strange problem on using renameTo(). I don't know why I can't rename to /mnt/desttest but it is ok to rename to /home/kit.ho/desttest. However, I already give every write permission to /mnt/. The return value is false while no specific reason. Who knows the reason?

import java.io.File;
public class renameFile {
    public static void main(String[] args) {
        File sourceFile = new File("/home/kit.ho/test");  
        File targetFile1 = new File("/mnt/desttest");  
        System.out.println("source file is exist? " + sourceFile.exists() + ", source file => " + sourceFile);  
        System.out.println(targetFile1 + " is exist? " + targetFile1.exists());  
        System.out.println("rename to " + targetFile1 + " => " + sourceFile.renameTo(targetFile1));  
        System.out.println("source file is exist? " + sourceFile.exists() + ", source file => " + sourceFile);   
    }
}

Edit: Finally, based on some answers, Rename function does not work on across file system, is there any workaround on this issue by not calling external command like "mv"?

skaffman
  • 398,947
  • 96
  • 818
  • 769
TheOneTeam
  • 25,806
  • 45
  • 116
  • 158
  • Is `/mnt` a separate partition? – Mechanical snail Aug 17 '11 at 03:54
  • Can you `mv /home/kit.ho/test /mnt/desttest` without problems? – Martin Aug 17 '11 at 03:54
  • @Mechanical: yes /mnt is on separate partition. – TheOneTeam Aug 17 '11 at 03:57
  • I dont' wanna use external process to rename a file – TheOneTeam Aug 17 '11 at 03:57
  • 2
    @Kit Ho: You *aren't* renaming a file; you're *moving* it across partitions. – Mechanical snail Aug 17 '11 at 03:59
  • What @Mechanical Snail said, Kit, you may want to brush up on what file system metadata is and how file systems actually work, the reason you cannot "rename to" across partitions is simple, the rename operation actually only changes the file metadata on the file system in question, it does not actually move any data. And since the /mnt doesnt actually contain the data yet, simply updating some metadata flags to point to a name would be pointless, there is no data for the name to point to. Thats why you always have to move(or copy) across partitions. – user439407 Aug 17 '11 at 05:00
  • @user439407: do u have any simple wordaround? – TheOneTeam Aug 17 '11 at 05:02
  • Moving the file of course, there is no one line way to do it in Java, this method looks pretty good http://stackoverflow.com/questions/300559/move-copy-file-operations-in-java – user439407 Aug 17 '11 at 06:19

4 Answers4

7

You can't do a rename across file systems (partitions).

jdigital
  • 11,926
  • 4
  • 34
  • 51
4

Create a method to copy file and call this method (that's what I use when renameTo() doesn't work):

void copyFile(File source, File destination) throws Exception {
  FileInputStream inputStream = new FileInputStream(source);
  FileOutputStream outputStream = new FileOutputStream(destination);
  int b = -1;
  while ((b = inputStream.read()) != -1) {
    outputStream.write(b);
  }
  inputStream.close();
  outputStream.close();
}

edit: if you want to move file, delete original after making a copy.

edit: even better would be FileUtils.moveFile() from Apache Commons library

jirka.pinkas
  • 918
  • 6
  • 21
  • `moveFile()` is the best way. The presented implementation is buggy (does not properly close streams) and inefficient (reads single bytes). If these things were left off for brevity, it should've been noted. – musiKk Aug 25 '11 at 09:29
  • sorry. I should have noted, that this is simplified for brevity. – jirka.pinkas Aug 27 '11 at 07:44
3

A simple 'don't reinvent the wheel' solution would be to use Apache Commons IO. It has FileUtils#moveFile() that takes care of handling different partitions.

Sbl
  • 67
  • 6
musiKk
  • 14,751
  • 4
  • 55
  • 82
1

File.renameTo may fail if you're moving across file systems, or if you're trying to overwrite an existing file. See the docs.

You also may have a problem since /mnt is a special purpose location and may have other attributes that prevent you from moving something into /mnt.

John Percival Hackworth
  • 11,395
  • 2
  • 29
  • 38