Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/371.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-如果名称已经存在,则重命名输出文件,并考虑现有增量_Java_Regex_Filenames_Increment - Fatal编程技术网

Java-如果名称已经存在,则重命名输出文件,并考虑现有增量

Java-如果名称已经存在,则重命名输出文件,并考虑现有增量,java,regex,filenames,increment,Java,Regex,Filenames,Increment,在构建一个Android应用程序时,我发现需要进行一些文件复制。我想通过在文件名中添加一个增量字符串,在使用allready文件名的情况下获取新文件名。比如说 text.txt ---> text(1).txt 算法应考虑以下因素 1如果存在text.txt,则新文件名永远不应为text.txt1 2如果存在text1.txt,则新文件名应为text2.txt,而不是text11.txt 3如果存在text1foo.txt,则新文件名应为text1foo1.txt 第一个我已经准备好了,

在构建一个Android应用程序时,我发现需要进行一些文件复制。我想通过在文件名中添加一个增量字符串,在使用allready文件名的情况下获取新文件名。比如说

text.txt ---> text(1).txt
算法应考虑以下因素

1如果存在text.txt,则新文件名永远不应为text.txt1

2如果存在text1.txt,则新文件名应为text2.txt,而不是text11.txt

3如果存在text1foo.txt,则新文件名应为text1foo1.txt

第一个我已经准备好了,但是第二个我有困难。正则表达式不是我的强项!使用正则表达式不是强制性的。每种方法都欢迎一些帮助

答复:

结合我的原始代码和这里的一个答案,我得出了这样一个结论,无论文件是否有扩展名,它在任何情况下都非常适合我:

public static File getFinalNewDestinationFile(File destinationFolder, File fileToCopy){

    String destFolderPath = destinationFolder.getAbsolutePath()+File.separator;
    File newFile = new File(destFolderPath + fileToCopy.getName());
    String filename=fileToCopy.getName();
    String nameWithoutExtentionOrIncrement;
    String extension = getFileExtension(filename); 

    if(extension!=null){
        extension="."+extension;
        int extInd = filename.lastIndexOf(extension);
        nameWithoutExtentionOrIncrement = new StringBuilder(filename).replace(extInd, extInd+extension.length(),"").toString();
    }
    else{ 
        extension=""; 
        nameWithoutExtentionOrIncrement = filename;
    }

    int c=0;
    int indexOfClose = nameWithoutExtentionOrIncrement.lastIndexOf(")");
    int indexOfOpen = nameWithoutExtentionOrIncrement.lastIndexOf("(");

    if(indexOfClose!=-1 && indexOfClose!=-1 && indexOfClose==nameWithoutExtentionOrIncrement.length()-1 && indexOfClose > indexOfOpen && indexOfOpen!=0){
        String possibleNumber = nameWithoutExtentionOrIncrement.substring(indexOfOpen+1, indexOfClose);
        try{
            c = Integer.parseInt(possibleNumber);
            nameWithoutExtentionOrIncrement=nameWithoutExtentionOrIncrement.substring(0, indexOfOpen);
        }catch(Exception e){c=0;}
    } 

    while(newFile.exists()){
        c++; 
        String path = destFolderPath + nameWithoutExtentionOrIncrement +"(" + Integer.toString(c) + ")" + extension;
        newFile = new File(path);
    }
    return newFile;
}



    public static String getFileExtension(String filename) {
        if (filename == null) {  return null; }
        int lastUnixPos = filename.lastIndexOf('/');
        int lastWindowsPos = filename.lastIndexOf('\\');
        int indexOfLastSeparator = Math.max(lastUnixPos, lastWindowsPos);
        int extensionPos = filename.lastIndexOf('.');
        int lastSeparator = indexOfLastSeparator;
        int indexOfExtension = lastSeparator > extensionPos ? -1 : extensionPos;
        int index = indexOfExtension;
        if (index == -1) {
            return null;
        } else {
            return filename.substring(index + 1).toLowerCase();
        }
    }

我假设有两件事:

1名为fileExistsString fileName的方法可用。如果文件系统中已存在具有指定名称的文件,则返回true

2有一个名为FILE_NAME的常量,在您的示例中,该常量等于text

if (!fileExists(FILE_NAME)) {
    //create file with FILE_NAME.txt as name
}

int availableIndex = 1;
while (true) {
    if (!fileExists(currentName)) {
        //create file with FILE_NAME(availableIndex).txt
        break;
    }
    availableIndex++;
}

我假设有两件事:

1名为fileExistsString fileName的方法可用。如果文件系统中已存在具有指定名称的文件,则返回true

2有一个名为FILE_NAME的常量,在您的示例中,该常量等于text

if (!fileExists(FILE_NAME)) {
    //create file with FILE_NAME.txt as name
}

int availableIndex = 1;
while (true) {
    if (!fileExists(currentName)) {
        //create file with FILE_NAME(availableIndex).txt
        break;
    }
    availableIndex++;
}

我对Android不是很确定,但因为它是一个Java程序,所以您可以创建要写入的目录的文件对象。 一旦你有了它,你就可以看到里面已经存在的文件名列表和其他相关信息。然后您可以根据上述逻辑确定文件名

File dir = new File("<dir-path>");
if(dir.isDirectory()){
        String[] files = dir.list();
        for(String fileName : files){
            <logic for finding filename>
        }
    }

我对Android不是很确定,但因为它是一个Java程序,所以您可以创建要写入的目录的文件对象。 一旦你有了它,你就可以看到里面已经存在的文件名列表和其他相关信息。然后您可以根据上述逻辑确定文件名

File dir = new File("<dir-path>");
if(dir.isDirectory()){
        String[] files = dir.list();
        for(String fileName : files){
            <logic for finding filename>
        }
    }

如果所有文件名都有一个扩展名,您可以这样做,只是一个示例,您必须将其更改为适用于您的情况:

public static void main(String[] args)
{
    String test  = "test(1)foo.txt";
    String test1 = "test(1)foo(1).txt";
    Pattern pattern = Pattern.compile("((?<=\\()\\d+(?=\\)\\.))");

    Matcher matcher = pattern.matcher(test);
    String fileOutput = "";
    String temp = null;
    int newInt = -1;
    while(matcher.find())
    {
        temp = matcher.group(0);
    }
    if(temp != null)
    {
        newInt = Integer.parseInt(temp);
        newInt++;
        fileOutput = test.replaceAll("\\(\\d+\\)(?=\\.(?!.*\\.))", "(" + newInt + ")");
    }
    else
    {
        fileOutput = test;
    }
    System.out.println(fileOutput);
    matcher = pattern.matcher(test1);
    fileOutput = "";
    temp = null;
    while(matcher.find())
    {
        temp = matcher.group(0);
    }
    if(temp != null)
    {
        newInt = Integer.parseInt(temp);
        newInt++;
        fileOutput = test1.replaceAll("\\(\\d+\\)(?=\\.(?!.*\\.))", "(" + newInt + ")");
    }
    else
    {
        fileOutput = test1;
    }
    System.out.println(fileOutput);
}
输出:

test1foo.txt

test1foo2.txt

它使用正则表达式在最后一个之前的右边查找数字

更新


replaceAll已更改,以处理发生故障的情况。在test1.foo1.txt中的第一个1之后。

如果所有文件名都有一个扩展名,您可以执行类似的操作,这只是一个示例,您必须将其更改为适用于您的情况:

public static void main(String[] args)
{
    String test  = "test(1)foo.txt";
    String test1 = "test(1)foo(1).txt";
    Pattern pattern = Pattern.compile("((?<=\\()\\d+(?=\\)\\.))");

    Matcher matcher = pattern.matcher(test);
    String fileOutput = "";
    String temp = null;
    int newInt = -1;
    while(matcher.find())
    {
        temp = matcher.group(0);
    }
    if(temp != null)
    {
        newInt = Integer.parseInt(temp);
        newInt++;
        fileOutput = test.replaceAll("\\(\\d+\\)(?=\\.(?!.*\\.))", "(" + newInt + ")");
    }
    else
    {
        fileOutput = test;
    }
    System.out.println(fileOutput);
    matcher = pattern.matcher(test1);
    fileOutput = "";
    temp = null;
    while(matcher.find())
    {
        temp = matcher.group(0);
    }
    if(temp != null)
    {
        newInt = Integer.parseInt(temp);
        newInt++;
        fileOutput = test1.replaceAll("\\(\\d+\\)(?=\\.(?!.*\\.))", "(" + newInt + ")");
    }
    else
    {
        fileOutput = test1;
    }
    System.out.println(fileOutput);
}
输出:

test1foo.txt

test1foo2.txt

它使用正则表达式在最后一个之前的右边查找数字

更新


replaceAll已更改,以处理发生故障的情况。在test1.foo1.txt中的第一个1之后。

这里有一种方法:

    String fileName;
    File file = new File(fileName);

    if(file.exists()) {
        int dot = fileName.lastIndexOf('.'), open = fileName.lastIndexOf('('), incr;
        boolean validNum = false;

        if(fileName.charAt(dot-1) == ')' && open != -1){
            String n = fileName.substring(open+1, dot-1);
            try {
                incr = Integer.parseInt(n);
                validNum = true;
            } catch(NumberFormatException e) {
                validNum = false;
            }
        }

        if(validNum) {
            String pre = fileName.substring(0, open+1), post = fileName.substring(0, dot-1);
            while(new File(pre + ++incr + post).exists());
            fileName = pre + incr + post;
        } else {
            fileName = fileName.substring(0, dot) + "(1)" + fileName.substring(dot); 
        }
    }

这里有一种方法:

    String fileName;
    File file = new File(fileName);

    if(file.exists()) {
        int dot = fileName.lastIndexOf('.'), open = fileName.lastIndexOf('('), incr;
        boolean validNum = false;

        if(fileName.charAt(dot-1) == ')' && open != -1){
            String n = fileName.substring(open+1, dot-1);
            try {
                incr = Integer.parseInt(n);
                validNum = true;
            } catch(NumberFormatException e) {
                validNum = false;
            }
        }

        if(validNum) {
            String pre = fileName.substring(0, open+1), post = fileName.substring(0, dot-1);
            while(new File(pre + ++incr + post).exists());
            fileName = pre + incr + post;
        } else {
            fileName = fileName.substring(0, dot) + "(1)" + fileName.substring(dot); 
        }
    }

使用一个正则表达式模式:

final static Pattern PATTERN = Pattern.compile("(.*?)(?:\\((\\d+)\\))?(\\.[^.]*)?");

String getNewName(String filename) {
    if (fileExists(filename)) {
        Matcher m = PATTERN.matcher(filename);
        if (m.matches()) {
            String prefix = m.group(1);
            String last = m.group(2);
            String suffix = m.group(3);
            if (suffix == null) suffix = "";

            int count = last != null ? Integer.parseInt(last) : 0;

            do {
                count++;
                filename = prefix + "(" + count + ")" + suffix;
            } while (fileExists(filename));
        }
    }
    return filename;
}
正则表达式模式解释:

.*? 一个非贪婪的匹配一切从一开始 ?:\\\\d+\\?括号中的数字是可选的 ?:uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu ___\\______\\_-火柴和 ______\\d+___;-匹配并捕获一个或多个数字 \\.[^.]+? 点后跟除点以外的任何选项(可选)
使用一个正则表达式模式:

final static Pattern PATTERN = Pattern.compile("(.*?)(?:\\((\\d+)\\))?(\\.[^.]*)?");

String getNewName(String filename) {
    if (fileExists(filename)) {
        Matcher m = PATTERN.matcher(filename);
        if (m.matches()) {
            String prefix = m.group(1);
            String last = m.group(2);
            String suffix = m.group(3);
            if (suffix == null) suffix = "";

            int count = last != null ? Integer.parseInt(last) : 0;

            do {
                count++;
                filename = prefix + "(" + count + ")" + suffix;
            } while (fileExists(filename));
        }
    }
    return filename;
}
正则表达式模式解释:

.*? 一个非贪婪的匹配一切从一开始 ?:\\\\d+\\?括号中的数字是可选的 ?:uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu ___\\______\\_-火柴和 ______\\d+___;-匹配并捕获一个或多个数字 \\.[^.]+? 点后跟除点以外的任何选项(可选)
你必须使用正则表达式吗?看来你可以做得更容易,否则..不,这不是强制性的…我只是想,ti会更有效的方式。欢迎任何方法!您不能在正则表达式中递增数字。@noob但您可以使用正则表达式提取需要递增的部分,以及需要保持不变的部分。是否必须使用正则表达式?看来你可以做得更容易,否则..不,这不是强制性的…我只是想,ti会更有效的方式。欢迎任何方法!您不能在正则表达式中递增数字。@noob但您可以使用正则表达式提取需要递增的部分,以及需要保持不变的部分。非常优雅和快速的方法可能会重复。唯一的缺点是,如果文件以结尾。增量添加在..之后。。示例foo.->foo.1在以前没有扩展的地方添加扩展。@Anonymous将正则表达式的结尾从\\.[^.]+?至\\.[^.]*?还有福。将成为一种非常优雅和快捷的方式。唯一的缺点是,如果文件以结尾。增量添加在..之后。。示例foo.->foo.1在以前没有扩展的地方添加扩展。@Anonymous更改正则表达式f的结尾 rom\\.[^.]+?至\\.[^.]*?还有福。将成为foo1。