【问题标题】:Java File.renameTo(File) not workingJava File.renameTo(文件)不起作用
【发布时间】:2012-08-20 01:40:26
【问题描述】:

我正在尝试列出目录的内容,并重命名某些文件。

public void run(String dirName) {
    try {
        File parDir = new File(dirName);
        File[] dirContents = parDir.listFiles();

        // Rename if necessary
        for(File f : dirContents) {
            System.out.println("f is:\n" + f.toString());
            String name = f.getName();
            String subbedName = name.replaceAll("\uFFFD", "_");

            System.out.println("\n" + "name = " + name + ", subbedName = " + subbedName + "\n");

            if(!name.equals(subbedName)) {
                File newFile = new File(f.getParentFile(), subbedName);
                System.out.println("newFile is:\n" + newFile.toString());
                if(!f.renameTo(newFile))
                    System.out.println("Tried to change file name but couldn't.");
            }
        }
    }
    catch(Exception exc1) {
        System.out.println("Something happened while listing and renaming directory contents: " + exc1.getMessage());
    }
}

当我运行它时,我得到“Tried to change file name but couldn't.”我不相信 Java 认为这些文件是“开放的”,所以我认为这不是原因。我什至跑过chmod 777 myDir,其中myDir 是传递给run 方法的dirName 字符串的值。

我在这里缺少什么?为什么 Java 不重命名这些文件?这些是 CentOS 机器。

编辑:为fnewFile 添加了打印输出,如下所示:

f is:
/root/path/to/mydir/test�.txt

newFile is:
/root/path/to/mydir/test_.txt

【问题讨论】:

    标签: java file-io rename


    【解决方案1】:

    您需要使用这些文件的完整 路径名创建新的File 对象。所以

    String name = f.getName(); // gets the name without the directory
    

    应该是:

    String name = f.getAbsolutePath();
    

    (您的搜索/替换可能需要更改)

    【讨论】:

    • 谢谢@Brian Agnew (+1) - 我听从了你的建议,但得到了相同的结果。有任何想法吗?再次感谢!
    【解决方案2】:

    问题在于f.getName() 返回由f 表示的路径的姓氏部分。然后,您按摩此字符串并将其转回File。但File 现在表示相对于当前目录的路径,而不是包含原始路径的目录。

    因此,您的代码实际上是在尝试将文件从 dirName 重命名到应用程序的当前目录中。这可能会失败,因为当前目录中已经存在具有这些名称的文件,或者因为 dirName 和当前目录位于不同的文件系统中。 (您不能将文件从一个文件系统重命名为另一个文件系统……您必须复制它。)

    请注意,Java 中的File 表示路径名,而不是文件或文件夹。在您的代码中,f 对象是由字符串dirname 表示的目录中文件系统对象(文件或文件夹)的路径名。这些f 对象中的每一个都有一个目录部分。


    修复代码的方法不止一种;例如

    • name = f.getName() 更改为name = f.toString()
    • new File(subbedName) 更改为new File(f.getParentFile(), subbedName)

    我有一个替代/附加理论。

    包含\uFFFD 字符的文件的路径名显示为“mojibake”;即当您使用错误的编码显示编码文本时得到的那种乱码文本。由于我们看到 3 个字符的乱码文本,我怀疑它试图将 \uFFFD 的 UTF-8 渲染显示为 Latin-1。

    所以我的理论是,当File.renameTo 方法将f 转换为它将提供给系统调用的形式时,也会发生同样的想法。由于某种我不清楚的原因,Java 可能使用了错误的编码,因此为原始文件生成了一个与文件系统中的文件名不匹配的“名称”。这足以导致重命名失败。

    可能相关的问题/链接:

    【讨论】:

    • 感谢@Stephen C (+1) - 感谢您的帮助,但这些建议都不起作用。仍然收到“厌倦更改文件名但无法更改文件名”打印输出...
    • 打印出 fFile 您尝试将其重命名为失败时,并将其添加到您的问题中。
    • 再次感谢 - 请查看我的编辑(为 fnewFile 添加了代码/打印输出,并将其输出添加到问题的底部)。
    【解决方案3】:

    f.getName(); 只返回文件夹的名称,而不是完整路径。所以subbedName 变成了一个相对路径文件。改用f.getCanonicalPath() 试试。

    【讨论】:

    • 谢谢@sp00m (+1) - 请在 Brian Agnew 的回答下方查看我的评论 - 我有同样的问题要问你。再次感谢!
    猜你喜欢
    • 2014-09-21
    • 2016-04-25
    • 1970-01-01
    • 1970-01-01
    • 2017-10-21
    • 2017-08-01
    • 2018-04-08
    • 2013-04-05
    • 1970-01-01
    相关资源
    最近更新 更多