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:
- 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.
- 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.