我有一个程序,我必须重命名一组文件夹。它们都是“ID [Name]”格式,我想将它们重命名为“Name [ID]”。 (它更像是对我的训练,学习java))
问题是,如果必须重命名的文件夹数量超过20-24。该程序将无法正常工作,并将给出文件错误的名称。 (重命名过程成功,但名称错误) 但如果它们低于20个文件夹,它可以很好地工作。(使用相同的文件夹进行测试)这是整个代码:
public class DirRename {
private String parentDir;
private DirectoryStream<Path> fileList;
public DirRename(final Path dir)
{
parentDir = dir.toString();
if(!Files.exists(dir) || !Files.isDirectory(dir) || !Files.isReadable(dir))
System.out.println("Directory Read Error!!!");
//filter to return only directories in parent folder
DirectoryStream.Filter<Path> dirOnlyFilter =
new DirectoryStream.Filter<Path>() {
public boolean accept(Path file) throws IOException {
return (Files.isDirectory(file));
}
};
try
{
fileList = Files.newDirectoryStream(dir,dirOnlyFilter);
}
catch(IOException | DirectoryIteratorException x)
{
System.err.println(x);
}
}
public void rename()
{
for(Path filepath : fileList)
{
String name = filepath.getFileName().toString();
File inFile = filepath.toFile();
if(!inFile.exists() || !inFile.isDirectory() || !inFile.canWrite())
{
System.out.println("Directory is not writeable");
return;
}
Pattern regex = Pattern.compile("((?:[\\w\\d]*(?:\\s|-){0,2}[\\w\\d]+)*)\\s*-*\\s*(?:\\[|\\Q(\\E)(.+)(?:\\]|\\Q)\\E)$");
Matcher match = regex.matcher(name);
while(match.find())
{
String gameID = match.group(1);
String gameName = match.group(2);
String rename = parentDir+File.separator+gameName+" ["+gameID+"]";
File toFile = new File(rename);
if(!Paths.get(rename).isAbsolute())
{
System.out.println("Cannot rename "+name+"to "+rename);
return;
}
if(inFile.renameTo(toFile))
System.out.println("Success!");
else
System.out.println("Renaming Failed!!! for "+rename);
}
}
}
}
我尝试使用“system.out.println(toFile.getName())”检查名称,同时删除“inFile.renameTo(toFile)”行。所有名字都是正确的。 但当我添加该行时,相同的名称打印不正确。(虽然一些正确打印的名称被错误地重命名)
我完全糊涂了。我是java的新手,通常不及一个noob程序员。有人可以告诉我发生了什么事吗?
非常感谢
编辑:我发现了问题。循环:
for(Path filepath : fileList){}
运行116次,而我只有64个文件夹。我找不到任何关于为什么会发生这种情况的解释,我使用相同的循环仅在以下函数中打印文件夹名称,并且它运行了64次。(确切地说,我有多少个文件夹)
public void printFolders()
{
for(Path filepath : fileList)
System.out.println(filepath.getFileName());
}
答案 0 :(得分:0)
好吧我终于解决了我自己的问题。这是我对为什么会发生这种情况的猜测(我不知道DirectoryStream的内部工作所以它只是一个猜测)。
当文件夹超过几个时,流将读取以前重命名的文件夹并将它们添加为新文件夹,因此它们被重命名两次。要么将名称更改回原始名称,要么将其变形(重命名不是100%重新适用)。 如果有几个文件夹,循环将在流有机会刷新之前结束,因此没有问题。 所以这就是我如何解决它。通过添加以下方法,并遍历路径数组而不是流。
private Path[] getVerifiedPaths()
{
ArrayList<Path> verifiedFilePaths= new ArrayList<>();
for(Path filepath : fileList)
verifiedFilePaths.add(filepath);
return verifiedFilePaths.toArray(new Path[0]);
}
Path[] filePaths = getVerifiedPaths();
for(Path filePath : filePaths) { ...rename...}
而不是:
for(Path filepath : fileList){...rename...}
感谢“JB Nizet”的建议(上面的评论)。