This now copies the file contents.
This implementation works perfectly on the example set below (you can literally copy and paste this into a java file and it will compile and do what you want). The only potential drawbacks are that it will skip 'versions' in between. So if it has A1.txt and A3.txt, it will only create A4.txt. It also cannot handle files without extensions, but I don't think that would matter much to you anyway.
It prints "Failure" if the file already exists or it otherwise fails in creating the file for some reason.
Note that you can specify the file directory on the command line or else it will use the current working directory.
It also recursively searches folders below, if you only want it to search the current/specified file directory, simple remove the else statement right before the return fileMap;
in the getFilesForFolder
method.
Before:
~/currentdirectory
- A1.txt
- A4.txt
- B1.txt
- ~/currentdirectory/asdf
After:
~/currentdirectory
- A1.txt
- A4.txt
- A5.txt
- B1.txt
- B2.txt
- ~/currentdirectory/asdf
- A1.txt
- A2.txt
- B1.txt
- B5.txt
- B6.txt
import java.io.File;
import java.io.IOException;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.Map;
import java.util.HashMap;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class Files {
static File folder;
static List<String> files;
public static void main(String[] args) {
if (args.length > 0)
folder = new File(args[0]);
else
folder = new File(System.getProperty("user.dir") + "/testfiles");
Map<File, Map<String, Integer>> files = new HashMap<File, Map<String, Integer>>();
files = getFilesForFolder(folder);
writeFile(files);
}
public static void writeFile(Map<File, Map<String, Integer>> files) {
String fileName;
for (Map.Entry<File, Map<String, Integer>> mapOfMapEntry : files.entrySet()) {
File originalFile = mapOfMapEntry.getKey();
for (Map.Entry<String, Integer> entry : (mapOfMapEntry.getValue()).entrySet()) {
fileName = entry.getKey();
try {
int i = fileName.contains(".") ? fileName.lastIndexOf('.') : fileName.length();
fileName = fileName.substring(0, i) + Integer.toString(entry.getValue() + 1) + fileName.substring(i);
File file = new File(fileName);
if (file.createNewFile()) {
System.out.println("Success: " + file.getAbsolutePath());
//File originalFile = new File(entry.getKey());
InputStream in = new FileInputStream(originalFile);
OutputStream out = new FileOutputStream(file);
byte[] buffer = new byte[1024];
int length;
while ((length = in.read(buffer)) > 0) {
out.write(buffer, 0, length);
}
in.close();
out.close();
} else {
//currently has duplicate value in map
//I tried to remove them but it was taking too long to debug
//I might come back to it later,
//otherwise you're just wasting a bit of computational resources
//by trying to create the same file multiple times
System.out.println("Failure: " + file.getAbsolutePath());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
//note this is recursive and will search files
//in subdirectories. you can change this by removing the else clause before return map
public static Map<File, Map<String, Integer>> getFilesForFolder(File folder) {
Map<File, Map<String, Integer>> mapOfMap = new HashMap<File, Map<String, Integer>>();
Map<String, Integer> fileMap = new HashMap<String, Integer>();
Integer number;
//any non-digit character 0-inf amount of times, any digit character, 0-inf amount of times,
//then a period, then the rest of the extension
Pattern pattern = Pattern.compile("(\\D*)(\\d*)(\\.\\w*)?");
//match each file in the file directory with the above regex expr
for (final File fileEntry : folder.listFiles()) {
if (!(fileEntry.isDirectory())) {
Matcher m = pattern.matcher(fileEntry.getAbsolutePath());
while (m.find()) {
number = fileMap.get(m.group(1) + m.group(3));
if (number != null) {
//the key/value already exist in the filemap
//check to see if we should use the new number or not
if (Integer.parseInt(m.group(2)) > number) {
fileMap.put(m.group(1) + m.group(3), (Integer.parseInt(m.group(2))));
mapOfMap.put(fileEntry, fileMap);
}
} else if (!m.group(1).equals("")) {
//the map is empty and the file has no number appended to it
if (m.group(3) == null) {
fileMap.put(m.group(1), 0);
mapOfMap.put(fileEntry, fileMap);
} else {
//the map is empty and the file already has a number appended to it
fileMap.put(m.group(1) + m.group(3), (Integer.parseInt(m.group(2))));
mapOfMap.put(fileEntry, fileMap);
}
}
}
}
else {
for (Map.Entry<File, Map<String, Integer>> entry : getFilesForFolder(fileEntry).entrySet()) {
mapOfMap.put(entry.getKey(), entry.getValue());
}
}
}
return mapOfMap;
}
}