Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/358.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 奇怪的错误,使用File.RenameTo()_Java - Fatal编程技术网

Java 奇怪的错误,使用File.RenameTo()

Java 奇怪的错误,使用File.RenameTo(),java,Java,我有一个程序,其中我必须重命名一组文件夹。它们都是“ID[Name]”格式,我想将它们重命名为“Name[ID]”。(这对我来说更像是一种学习java的培训) 问题是,如果必须重命名的文件夹数量超过20-24个。该程序将无法工作,并将给文件错误的名称。(重命名过程成功,但名称错误) 但是,如果它们少于20个文件夹,它就可以完美地工作 以下是全部代码: public class DirRename { private String parentDir; private DirectoryStrea

我有一个程序,其中我必须重命名一组文件夹。它们都是“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);
        }
    }

}
}
运行116次,而我只有64个文件夹。我找不到任何解释来解释为什么会发生这种情况,我只在下面的函数中使用相同的循环来打印文件夹名称,并且它精确地运行了64次。(正好是我拥有的文件夹数)


好吧,我终于解决了我自己的问题。下面是我对发生这种情况的原因的猜测(我不知道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...}

感谢“JB Nizet”的建议(以上评论)。

定义“行不通”。会发生什么?什么是输入,什么是输出?正如我上面解释的。命名成功,但给文件夹起了错误的名字(有些保持不变,有些只是变得很奇怪,然后一些被正确重命名)。但是,如果必须重命名的文件夹数少于20,则所有文件夹都已正确重命名。这可能意味着这个糟糕的正则表达式是错误的。如果您提供了输入和输出,我可能会尝试确定问题的来源。但既然你想保守秘密,我的帮助也会像我说的那样保密。这些文件是“ID[Name]”格式的,我必须将它们重命名为“Name[ID]”。下面是我在测试中使用的完全相同的东西:当文件夹数低于20时,整个过程都会工作。相同的名称可以正常工作并正确重命名,但超过20个文件夹时会完全出错。所以我不认为正则表达式是错的。
public void printFolders()
{
    for(Path filepath : fileList)
        System.out.println(filepath.getFileName());
}
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...}