Java File.renameTo(File) 不起作用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12110278/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 07:37:13  来源:igfitidea点击:

Java File.renameTo(File) not working

javafile-iorename

提问by IAmYourFaja

I'm trying to list a directory's contents, and rename certain files.

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

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

When I run this, I get "Tried to change file name but couldn't." I don't believethat Java is considering these files to be "open", so I don't think that's the reason. I've even ran chmod 777 myDirwhere myDiris the value of the dirNamestring passed into the runmethod.

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

What am I missing here? Why won't Java rename these file(s)? These are CentOS machines.

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

Edit: Added printouts for both fand newFile, which is as follows:

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

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

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

回答by Brian Agnew

You need to create your new Fileobject with the fullpathname of those files. So

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

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

should likely be:

应该是:

String name = f.getAbsolutePath();

(your search/replace may need to change)

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

回答by Stephen C

The problem is that f.getName()returns the last name component of the path that is represented by f. You then massage this String and turn it back into a File. But the Filenow represents a path relative to the current directory, not the directory containing the original path.

问题是f.getName()返回由f. 然后你按摩这个字符串并将它变成一个File. 但是Filenow 表示相对于当前目录的路径,而不是包含原始路径的目录。

As a result your code is actually attempting to rename the files from dirNameinto the application's current directory. That could fail because files already exist in the current directory with those names, or because the dirNameand the current directory are in different file systems. (You cannot rename a file from one filesystem to another ... you have to copyit.)

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

Please note that a Filein Java represents a pathname, not a file or a folder. In your code, the fobjects are the pathnames for file system objects (either files or folders) in the directory denoted by the String dirname. Each of these fobjects willhave a directory part.

请注意,FileJava中的 a代表路径名,而不是文件或文件夹。在您的代码中,f对象是由 String 表示的目录中文件系统对象(文件或文件夹)的路径名dirname。所有这些的f对象有一个目录的一部分。



There is more than one way to fix your code; for example

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

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


I have an alternative / additional theory.

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

The pathname of the file containing the \uFFFDcharacter is coming out as "mojibake"; i.e. the kind of garbled text that you get when you display encoded text using the wrong encoding. And since we are seeing 3 characters of garbled text, I suspect that it is attempting to display the UTF-8 rendering of \uFFFDas Latin-1.

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

So my theory is that the same think is happening when the File.renameTomethod is converting fto the form that it is going to provide to the system call. For some reason that is no clear to me, Java could be using the wrong encoding, and as a result producing a "name" for the original file that doesn't match the name of the file in the file system. That would be sufficient to cause the rename to fail.

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

Possibly related questions / links:

可能相关的问题/链接:

回答by sp00m

f.getName();only returns the name of the folder, not the full path. So subbedNamebecomes a relative path file. Try something with f.getCanonicalPath()instead.

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