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
Java File.renameTo(File) not working
提问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 myDir
where myDir
is the value of the dirName
string passed into the run
method.
当我运行它时,我得到“ Tried to change file name but couldn't.
” 我不相信Java 认为这些文件是“开放的”,所以我认为这不是原因。我什至跑过传递给方法的字符串的值在chmod 777 myDir
哪里。myDir
dirName
run
What am I missing here? Why won't Java rename these file(s)? These are CentOS machines.
我在这里错过了什么?为什么 Java 不重命名这些文件?这些是 CentOS 机器。
Edit: Added printouts for both f
and 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 File
object 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 File
now represents a path relative to the current directory, not the directory containing the original path.
问题是f.getName()
返回由f
. 然后你按摩这个字符串并将它变成一个File
. 但是File
now 表示相对于当前目录的路径,而不是包含原始路径的目录。
As a result your code is actually attempting to rename the files from dirName
into the application's current directory. That could fail because files already exist in the current directory with those names, or because the dirName
and 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 File
in Java represents a pathname, not a file or a folder. In your code, the f
objects are the pathnames for file system objects (either files or folders) in the directory denoted by the String dirname
. Each of these f
objects willhave a directory part.
请注意,File
Java中的 a代表路径名,而不是文件或文件夹。在您的代码中,f
对象是由 String 表示的目录中文件系统对象(文件或文件夹)的路径名dirname
。所有这些的f
对象将有一个目录的一部分。
There is more than one way to fix your code; for example
修复代码的方法不止一种;例如
- change
name = f.getName()
toname = f.toString()
- change
new File(subbedName)
tonew 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 \uFFFD
character 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 \uFFFD
as Latin-1.
包含\uFFFD
字符的文件的路径名显示为“mojibake”;即当您使用错误的编码显示编码文本时得到的那种乱码。并且由于我们看到 3 个字符的乱码文本,我怀疑它正在尝试将 UTF-8 渲染显示\uFFFD
为 Latin-1。
So my theory is that the same think is happening when the File.renameTo
method is converting f
to 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:
可能相关的问题/链接:
- File name charset problem in java
- http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4733494(Note that Sun decided this was not a Java bug, and most of the "me too" comments on the bug report are from people who do not understand the explanation ...)
- java中的文件名字符集问题
- http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4733494(请注意,Sun 认为这不是 Java 错误,并且错误报告中的大多数“我也是”评论来自那些不理解解释...)
回答by sp00m
f.getName();
only returns the name of the folder, not the full path. So subbedName
becomes a relative path file. Try something with f.getCanonicalPath()
instead.
f.getName();
只返回文件夹的名称,而不是完整路径。所以subbedName
就变成了相对路径文件。尝试一些东西f.getCanonicalPath()
。