Java File.renameTo(File)不起作用

时间:2012-08-24 13:24:01

标签: java file-io rename

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

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是传递到dirName方法的run字符串的值。

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

修改:为fnewFile添加了打印输出,如下所示:

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

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

3 个答案:

答案 0 :(得分: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可能使用了错误的编码,因此产生了原始文件的“名称”,该名称与文件系统中的文件名不匹配。这足以导致重命名失败。

可能相关的问题/链接:

答案 1 :(得分:1)

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

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

应该是:

String name = f.getAbsolutePath();

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

答案 2 :(得分:1)

f.getName();仅返回文件夹的名称,而不是完整路径。因此subbedName成为相对路径文件。尝试使用f.getCanonicalPath()代替。