0

我有一个程序,我必须在其中重命名一组文件夹。它们都是“ID [名称]”格式,我想将它们重命名为“名称 [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());
}
4

1 回答 1

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”的建议(上面的评论)。

于 2013-07-18T18:58:36.650 回答