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

Ano*_*ous 1 java regex filenames increment

构建一个 Android 应用程序 我遇到了需要进行一些文件复制的问题。我想要一种通过在文件名中添加“(增量)”字符串来在文件名已被使用的情况下获取新文件名的方法。例如

text.txt ---> text(1).txt
Run Code Online (Sandbox Code Playgroud)

该算法应考虑以下因素

1) 如果text.txt存在,新文件名应该NEVERtext.txt(1)

2)如果text(1).txt存在,那么新的文件名应该是text(2).txttext(1)(1).txt

3) 如果text(1)foo.txt存在,新文件名应该是text(1)foo(1).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();
        }
    }
Run Code Online (Sandbox Code Playgroud)

AJN*_*eld 7

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

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;
}
Run Code Online (Sandbox Code Playgroud)

正则表达式模式解释:

  • (.*?) 从头开始的非贪婪的“匹配一切”
  • (?:\\((\\d+)\\))? 括号中的数字(可选)
    • (?:____________) - 是一个非捕获组
    • ___\\(______\\)_- 匹配()
    • ______(\\d+)____ - 匹配并捕获一位或多位数字
  • (\\.[^.]+)? 一个点后跟一个点以外的任何东西(可选)