Home > OS >  How to write a method that increments a file name in java
How to write a method that increments a file name in java

Time:10-12

I am writing a method that takes a a string of html and writes it to a file. The method should increment the file name if the file already exists. For example, if wordmatch.html already exists then a new file should be created wordmatch1.html so and so fourth.

I have created a method that writes the html to a file. I'm working on the last part to incrementally change the name of a new file if the file already existst.

public void saveContent(WordMatch wordMatch){
    logger.info(wordMatch);
    try {
    File file = new File("wordmatch0.html");
    String html = wordMatch.toString();
    String cleanedHTML = html.replace("WordMatch(content=","").replace(")","");
    logger.info(cleanedHTML);
    if (file.createNewFile()) {
        System.out.println("File created: "   file.getName());
        try {
            FileWriter myWriter = new FileWriter("word_match.html");
            myWriter.write(cleanedHTML);
            myWriter.close();
            System.out.println("Successfully wrote to the file.");
        } catch (IOException e) {
            System.out.println("An error occurred.");
            e.printStackTrace();
        }
    } else {
        String fileName = file.getName().toString();
        String index = fileName.substring(fileName.indexOf("h")   1);
        index = index.substring(0, index.indexOf("."));
        Integer parsedInt = Integer.parseInt(index);
        System.out.println(parsedInt);
        parsedInt =1;
        fileName = fileName.replace(index,parsedInt.toString());
        System.out.println(fileName);
        System.out.println("fileName should have been printed by now");
        file = new File(fileName);
        FileWriter myWriter = new FileWriter(file);
        myWriter.write(cleanedHTML);
        myWriter.close();
        //TODO add method to write file name with new index
        System.out.println("File already exists.");
    }
    } catch (IOException e) {
    System.out.println("An error occurred.");
    e.printStackTrace();
    }
}

Any help with this would be greatly appreciated. Thanks.

CodePudding user response:

A simple approach will be count the number of files matching your file name and then increment the numberOfFiles to create a new file name :

Stream<Path> files = Files.list(Paths.get("C:\\your\\local\\path"));
long numberOfFiles = files.map(Path.class::cast)
                          .filter(path -> path.getFileName().toString().startsWith("wordmatch"))
                          .count();

After all you have to manage certains situations, to have a good algorithm for managing your files.

CodePudding user response:

A problem that seems trivial but has so many pitfalls.

The algorithm you wrote won't work for the following reasons:

  1. Simple if-else is not enough, you need to go through a loop to find the last index, because potentially there could be many files created already.
  2. Else block tries to find an index from the file name that should't have one.

Moreover, there are additional questions that may raise.

  • What if someone deleted the intermediate indexes and now you have 1 and 4, do you want to go with 2 or 5?
  • Can someone delete the files from the directory except the programm?
  • Are nested directories possible?
  • How often files are created?
  • Can someone manually create a file with a proper name bypassing the programm?

And more importand question is - do you really want to stick to the strict brute-force counter on the actual files listed in a directory?

If the answer is yes, the more reasonable would be to check the files using File.list(), sort them, take the last index and increment them instead of trying to create a file and increment on a failure.

public class Main {

    public static void main(String[] args) {
        File directoryPath = new File("path_to_your_dir");

        FilenameFilter filenameFilter = (dir, name) -> !dir.isFile();
        Integer maxIndex = Arrays.stream(directoryPath.list(filenameFilter))
                .map(name -> name.substring(name.lastIndexOf('.') - 1, name.lastIndexOf('.'))) // beware of file extensions!
                .map(Main::parseOrDefault)
                .max(Integer::compareTo)
                .orElse(-1);
        // -1 is no files, 0 if a file with no index, otherwise max index
        System.out.println(maxIndex);
    }

    private static Integer parseOrDefault(String integer) {
        try {
            return Integer.valueOf(integer);
        } catch (NumberFormatException e) {
            return 0;
        }
    }
}

If the answer is no, you can have a counter that is persisted somewhere (file system, BD) and incremented regardless every time. And more simple approach is establish a frequence of file creations and simply append a timestamp/date-time to the end of each file.

  •  Tags:  
  • java
  • Related