如何将文件重命名为另一个文件系统?

4

我在使用renameTo()时遇到了一个奇怪的问题。我不知道为什么无法将文件重命名为/mnt/desttest,但可以重命名为/home/kit.ho/desttest。然而,我已经给/mnt/赋予了所有写权限。返回值为false,但没有具体原因。谁知道原因?

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

编辑: 根据一些答案,重命名函数不能跨文件系统工作,是否有任何方法来解决这个问题,而不调用外部命令如“mv”?


/mnt 是一个单独的分区吗? - Mechanical snail
你能无问题地执行 mv /home/kit.ho/test /mnt/desttest 吗? - Martin
@Mechanical:是的,/mnt在单独的分区上。 - TheOneTeam
2
@Kit Ho:你并没有重命名文件;你是在不同分区之间移动它。 - Mechanical snail
机械蜗牛所说的,Kit,你可能需要了解一下文件系统元数据以及文件系统的实际工作原理。你不能跨分区“重命名”的原因很简单,重命名操作实际上只会更改所涉及文件系统上的文件元数据,而不会移动任何数据。由于/mnt目录实际上还没有包含数据,仅仅更新一些元数据标志来指向一个名称是毫无意义的,因为没有数据可以指向这个名称。这就是为什么你总是需要在分区之间移动(或复制)的原因。 - user439407
显示剩余3条评论
4个回答

7

如果文件系统(分区)不同,您无法进行重命名操作。


1
@Kit Ho:你需要将所有文件复制到 /mnt 目录下,然后删除原始文件。 - Denis Tulskiy

4
创建一个方法来复制文件,并调用此方法(当renameTo()不起作用时我使用这个方法):
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();
}

编辑:如果您想移动文件,请在复制后删除原始文件。

编辑:更好的方法是使用Apache Commons库中的FileUtils.moveFile()


moveFile() 是最好的方法。所提供的实现存在缺陷(未正确关闭流)且效率低下(读取单个字节)。如果为了简洁而省略了这些内容,应该进行说明。 - musiKk
抱歉,我应该注意到这是为了简洁而简化的。 - jirka.pinkas

3

一个简单的“不要重复造轮子”的解决方案是使用Apache Commons IO。它有一个FileUtils#moveFile()函数,可以处理不同分区的文件移动。


1

File.renameTo 可能会在跨文件系统移动或尝试覆盖现有文件时失败。请参阅文档

您还可能会遇到问题,因为 /mnt 是一个特殊目的位置,可能具有其他属性,防止您将某些内容移动到 /mnt 中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接