【问题标题】:Java fails in moving (renaming) a file when the resulting file is on another filesystem当生成的文件位于另一个文件系统上时,Java 无法移动(重命名)文件
【发布时间】:2012-05-10 09:59:46
【问题描述】:

我们在尝试将文件从一个目录移动到另一个目录时出错的程序。经过多次调试后,我通过编写一个小型实用程序来定位错误,该程序只是将文件从一个目录移动到另一个目录(下面的代码)。事实证明,虽然在本地文件系统上移动文件可以正常工作,但尝试将文件移动到另一个文件系统会失败。

这是为什么?问题可能是特定于平台的——如果这很重要,我们正在 ext3 上运行 Linux。

还有第二个问题;我应该使用 File 类的 renameTo() 方法以外的其他方法吗?似乎这只适用于本地文件系统。

测试(以 root 身份运行):

touch /tmp/test/afile

java FileMover /tmp/test/afile /root/
The file move was successful

touch /tmp/test/afile

java FileMover /tmp/test/afile /some_other_disk/
The file move was erroneous

代码:

import java.io.File;

public class FileMover {
    public static void main(String arguments[] ) throws Exception {
        boolean success;
        File file = new File(arguments[0]);
        File destinationDir = new File(arguments[1]);
        File destinationFile = new File(destinationDir,file.getName() );
        success = file.renameTo(destinationFile);
        System.out.println("The file move was " + (success?"successful":"erroneous"));
    }
}

【问题讨论】:

    标签: java linux filesystems


    【解决方案1】:

    Java 7 及以上版本

    使用Files.move(Path source, Path target, CopyOption... opts)

    请注意,在文件系统之间移动文件时不得提供ATOMIC_MOVE 选项。

    Java 6 及以下

    来自File.renameTo的文档:

    [...] 重命名操作可能无法将文件从一个文件系统移动到另一个文件系统 [...]

    显而易见的解决方法是“手动”复制文件,方法是打开一个新文件,将内容写入文件,然后删除旧文件。

    您也可以尝试 Apache Commons 的 FileUtils.moveFile 方法。

    【讨论】:

    • Err... 在我写我的时候没有加载你的答案:),moveFile 是救世主 +1
    • 您对 Apache Commons 的建议正是我的下一步。感谢您提供的内容丰富的答案,实际上回答了这两个问题!
    • 为了补充上面已经提供的出色答案,如果 oldpath 和 newpath 不在同一个已安装的文件系统上,则重命名中使用的系统调用将返回 EXDEV。事实上,诸如“mv”之类的程序通过执行显式复制和删除操作来处理这种情况。
    • 从 java 7 开始你可以使用 java.nio.file.Files.move 来处理不同的文件系统,但是你不能使用 ATOMIC_MOVE 选项。 docs.oracle.com/javase/7/docs/api/java/nio/file/…
    【解决方案2】:

    Javadoc 救援:

    此方法的行为的许多方面都与生俱来 平台相关:重命名操作可能无法移动 文件从一个文件系统到另一个文件系统,它可能不是原子的,它 如果具有目标抽象路径名的文件可能不会成功 已经存在。应始终检查返回值以确保 表示重命名操作成功。

    注意,Files 类定义了 move 方法来移动或重命名一个 以独立于平台的方式文件。

    【讨论】:

      【解决方案3】:

      来自文档:

      重命名此抽象路径名表示的文件。

      此方法的行为的许多方面都与生俱来 平台相关:重命名操作可能无法移动 文件从一个文件系统到另一个文件系统,它可能不是原子的,它 如果具有目标抽象路径名的文件可能不会成功 已经存在。应始终检查返回值以确保 表示重命名操作成功。

      如果你想在不同的文件系统之间移动文件,你可以使用 Apache 的moveFile

      【讨论】:

        【解决方案4】:

        你的 ider 是错误的 因为 /some_other_disk/ 是相对 url 但完全是 url,找不到 url 我有例子

        java FileMover D:\Eclipse33_workspace_j2ee\test\src\a\a.txt D:\Eclipse33_workspace_j2ee\test\src 文件移动成功

        java FileMover D:\Eclipse33_workspace_j2ee\test\src\a\a.txt\Eclipse33_workspace_j2ee\test\src

        文件移动错误

        结果是 url 错误

        【讨论】:

        • 任何以“/”开头的路径都是绝对路径(在 unices 上)。所以不行。请参阅上面的答案以了解实际回答问题的内容。
        猜你喜欢
        • 2011-10-28
        • 1970-01-01
        • 1970-01-01
        • 2023-04-06
        • 2020-08-22
        • 1970-01-01
        • 1970-01-01
        • 2021-03-14
        • 1970-01-01
        相关资源
        最近更新 更多