我试图列出一个目录的内容,并重命名某些文件。
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机器。
编辑:添加了两个的打印输出 f
以及 newFile
,具体如下:
f is:
/root/path/to/mydir/test�.txt
newFile is:
/root/path/to/mydir/test_.txt
3条答案
按热度按时间ckocjqey1#
f.getName();
只返回文件夹的名称,不返回完整路径。所以呢subbedName
成为相对路径文件。试着用它做点什么f.getCanonicalPath()
相反。2nc8po8w2#
你需要创建新的
File
对象的完整路径名。所以可能是:
(您的搜索/替换可能需要更改)
inb24sb23#
问题是
f.getName()
返回由表示的路径的姓氏组件f
. 然后你按摩这根绳子,把它变回一根绳子File
. 但是File
现在表示相对于当前目录的路径,而不是包含原始路径的目录。因此,您的代码实际上是在尝试重命名
dirName
到应用程序的当前目录中。这可能会失败,因为当前目录中已存在具有这些名称的文件,或者dirName
和当前目录在不同的文件系统中(不能将文件从一个文件系统重命名为另一个文件系统。。。你必须复制它。)请注意
File
在java中表示路径名,而不是文件或文件夹。在你的代码里f
对象是由字符串表示的目录中文件系统对象(文件或文件夹)的路径名dirname
. 每一个f
对象将有一个目录部分。修复代码的方法不止一种;例如
改变
name = f.getName()
至name = f.toString()
改变new File(subbedName)
至new File(f.getParentFile(), subbedName)
我有另外一个理论。包含
\uFFFD
这个角色被称为“莫吉巴克”;i、 e.当您使用错误的编码显示编码文本时得到的乱码文本的类型。由于我们看到了3个字符的乱码文本,我怀疑它试图显示\uFFFD
拉丁语-1。所以我的理论是当
File.renameTo
方法正在转换f
它将提供给系统调用的窗体。由于某些我不清楚的原因,java可能使用了错误的编码,结果为原始文件生成了一个与文件系统中的文件名不匹配的“名称”。这足以导致重命名失败。可能相关的问题/链接:
java中的文件名字符集问题
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4733494 (请注意,sun认为这不是一个java错误,错误报告中的大多数“我也是”评论都来自不理解解释的人……)