darshan
darshan

Reputation: 4569

How to increment the filename number if the file exists

How can I increment the filename if the file already exists?

Here's the code that I am using -

int num = 0;

String save = at.getText().toString() + ".jpg";

File file = new File(myDir, save);

if (file.exists()) {
    save = at.getText().toString() + num + ".jpg";

    file = new File(myDir, save);
    num++;
}

This code works, but only two files are saved, like file.jpg and file2.jpg.

Upvotes: 8

Views: 24433

Answers (10)

Bibin Baby
Bibin Baby

Reputation: 188

In addition to the first answer, I made some more changes:

private File getUniqueFileName(String folderName, String searchedFilename) {
    int num = 1;
    String extension = getExtension(searchedFilename);
    String filename = searchedFilename.substring(0, searchedFilename.lastIndexOf("."));
    File file = new File(folderName, searchedFilename);
    while (file.exists()) {
        searchedFilename = filename + "(" + (num++) + ")" + extension;
        file = new File(folderName, searchedFilename);
    }
    return file;
}

private String getExtension(String name) {
    return name.substring(name.lastIndexOf("."));
}

Upvotes: 1

nartoan
nartoan

Reputation: 378

This problem is to always initialize num = 0, so if file exists, it saves file0.jpg and does not check whether file0.jpg exists.

So, to code work. You should check until it is available:

int num = 0;
String save = at.getText().toString() + ".jpg";
File file = new File(myDir, save);
while(file.exists()) {
    save = at.getText().toString() + (num++) + ".jpg";
    file = new File(myDir, save);
}

Upvotes: 28

cpuchip
cpuchip

Reputation: 148

Having needed to solve this problem in my own code, I took Tejas Trivedi's answer, made it work like Windows when you happen to download the same file several times.

// This function will iteratively to find a unique file name to use when given a file: example (###).txt
// More or less how Windows will save a new file when one already exists: 'example.txt' becomes 'example (1).txt'.
// if example.txt already exists
private File getUniqueFileName(File file) {
    File originalFile = file;
    try {
        while (file.exists()) {
            String newFileName = file.getName();
            String baseName = newFileName.substring(0, newFileName.lastIndexOf("."));
            String extension = getExtension(newFileName);

            Pattern pattern = Pattern.compile("( \\(\\d+\\))\\."); // Find ' (###).' in the file name, if it exists
            Matcher matcher = pattern.matcher(newFileName);

            String strDigits = "";
            if (matcher.find()) {
                baseName = baseName.substring(0, matcher.start(0)); // Remove the (###)
                strDigits = matcher.group(0); // Grab the ### we'll want to increment
                strDigits = strDigits.substring(strDigits.indexOf("(") + 1, strDigits.lastIndexOf(")")); // Strip off the ' (' and ').' from the match
                // Increment the found digit and convert it back to a string
                int count = Integer.parseInt(strDigits);
                strDigits = Integer.toString(count + 1);
            } else {
                strDigits = "1"; // If there is no (###) match then start with 1
            }
            file = new File(file.getParent() + "/" + baseName + " (" + strDigits + ")" + extension); // Put the pieces back together
        }
        return file;
    } catch (Error e) {
        return originalFile; // Just overwrite the original file at this point...
    }
}

private String getExtension(String name) {
    return name.substring(name.lastIndexOf("."));
}

Calling getUniqueFileName(new File('/dir/example.txt') when 'example.txt' already exists while generate a new File targeting '/dir/example (1).txt' if that too exists it'll just keep incrementing number between the parentheses until a unique file is found, if an error happens, it'll just give the original file name.

I hope this helps some one needing to generate a unique file in Java on Android or another platform.

Upvotes: 2

Tejas Trivedi
Tejas Trivedi

Reputation: 130

This function returns the exact new file with an increment number for all kind of extensions.

private File getFileName(File file) {
    if (file.exists()) {
        String newFileName = file.getName();
        String simpleName = file.getName().substring(0, newFileName.indexOf("."));
        String strDigit = "";

        try {
            simpleName = (Integer.parseInt(simpleName) + 1 + "");
            File newFile = new File(file.getParent() + "/" + simpleName + getExtension(file.getName()));
            return getFileName(newFile);
        }
        catch (Exception e){
        }

        for (int i=simpleName.length()-1; i>=0; i--) {
            if (!Character.isDigit(simpleName.charAt(i))) {
                strDigit = simpleName.substring(i + 1);
                simpleName = simpleName.substring(0, i+1);
                break;
            }
        }

        if (strDigit.length() > 0) {
            simpleName = simpleName + (Integer.parseInt(strDigit) + 1);
        }
        else {
            simpleName += "1";
        }

        File newFile = new File(file.getParent() + "/" + simpleName + getExtension(file.getName()));
        return getFileName(newFile);
    }
    return file;
}

private String getExtension(String name) {
    return name.substring(name.lastIndexOf("."));
}

Upvotes: -1

JulienH
JulienH

Reputation: 11

This is the solution I use to handle this case. It works for folders as well as for files.

var destination = File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "MyFolder")

if (!destination.exists()) {
    destination.mkdirs()
} else {
    val numberOfFileAlreadyExist =
        destination.listFiles().filter { it.name.startsWith("MyFolder") }.size
    destination = File(
        Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS),
        "MyFolder(${numberOfFileAlreadyExist + 1})"
    )
    destination.mkdirs()
}

Upvotes: 0

SankarRaman
SankarRaman

Reputation: 1

Another simple logic solution to get the unique file name under a directory using Apache Commons IO using WildcardFileFilter to match the file name and get the number of exists with the given name and increment the counter.

public static String getUniqueFileName(String directory, String fileName) {
  String fName = fileName.substring(0, fileName.lastIndexOf("."));
  Collection<File> listFiles = FileUtils.listFiles(new File(directory), new WildcardFileFilter(fName + "*", IOCase.INSENSITIVE), DirectoryFileFilter.DIRECTORY);
  if(listFiles.isEmpty()) {
    return fName;
  }
  return fName.concat(" (" + listFiles.size() + ")");
}

Upvotes: 0

hardik parmar
hardik parmar

Reputation: 853

Kotlin version:

private fun checkAndRenameIfExists(name: String): File {
    var filename = name
    val extension = "pdf"
    val root = Environment.getExternalStorageDirectory().absolutePath
    var file = File(root, "$filename.$extension")
    var n = 0
    while (file.exists()) {
        n += 1
        filename = "$name($n)"
        file = File(root, appDirectoryName + File.separator + "$filename.$extension")
    }
    return file
}

Upvotes: 0

svarog
svarog

Reputation: 9839

You can avoid the code repetition of some of the answers here by using a do while loop

Here's an example using the newer NIO Path API introduced in Java 7

Path candidate = null;
int counter = 0;
do {
    candidate = Paths.get(String.format("%s-%d",
            path.toString(), ++counter));
} while (Files.exists(candidate));
Files.createFile(candidate);

Upvotes: 0

Kamran Ahmed
Kamran Ahmed

Reputation: 7761

Try this:

File file = new File(myDir, at.getText().toString() + ".jpg"); 

for (int num = 0; file.exists(); num++) {
    file = new File(myDir, at.getText().toString() + num + ".jpg");
}

// Now save/use your file here

Upvotes: 1

Ahmad Aghazadeh
Ahmad Aghazadeh

Reputation: 17131

int i = 0;
String save = at.getText().toString();
String filename = save +".jpg";
File f = new File(filename);
while (f.exists()) {
    i++;
    filename =save+ Integer.toString(i)+".jpg";
    f = new File(filename);
}
f.createNewFile();

Upvotes: 0

Related Questions