簡體   English   中英

Java-重命名輸出文件(如果名稱已經存在且具有增量),請考慮到現有的增量

[英]Java - renaming output file if name already exists with an increment, taking into account existing increments

構建一個Android應用程序時,我遇到了進行一些文件復制的需求。 我想通過在文件名中添加“(increment)”字符串來獲取已使用文件名的新文件名的方法。 例如

text.txt ---> text(1).txt

算法應說明以下問題

1)如果text.txt存在,則新文件名NEVER應該是text.txt(1)

2)如果text(1).txt存在,則新文件名應為text(2).txt而不是text(1)(1).txt

3)如果text(1)foo.txt存在,則新文件名應為text(1)foo(1).txt

我已經准備好了第一個,但是第二個卻遇到了困難。 正則表達式不是我的強項!(使用Regex不是強制性的。歡迎使用每種方法)有幫助嗎?

回答:

結合我的原始代碼和這里的答案之一,我最終得出了結論,無論文件是否具有擴展名,它在所有情況下都對我非常有效:

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();
        }
    }

使用一種正則表達式模式:

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+)\\\\))? 括號中的數字(可選)
    • (?:____________) -是一個非捕獲組
    • ___\\\\(______\\\\)_匹配()
    • ______(\\\\d+)____匹配並捕獲一個或多個數字
  • (\\\\.[^.]+)? 點號后跟除點號之外的任何內容(可選)

這是一種實現方法:

    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); 
        }
    }

我假設幾件事:

1)可以使用一種名為fileExists(String 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對象。 有了它后,您可以看到其中已經存在的文件名列表以及其他相關信息。 然后,您可以根據上述邏輯確定文件名。

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);
}

輸出:

測試(1)foo.txt

測試(1)富(2).txt

它使用正則表達式在last之前的()查找數字.

更新資料

replaceAll()更改為處理存在的情況. test(1).foo(1).txt的第一個(1)之后。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM