I'm trying to check if a directory exists, if that happens I want to give it another number, for example, if "folderX" exists I want to create a new one called "FolderX1", at the moment I'm just able to do this once since I have it on an if/else statement like this:
File fa = new File(folder);
if(!fa.exists()){
this.folder = folder;
}else{
this.folder = folder+=1;
}
I want do this recursively, If the program detects that "folderX" exists it should jump and check the others (folderX,FolderX1,FolderX2, etc) until it finds one that can be created but i don't know how to do it.
Basically, you need some kind of loop that can determine if the incrementing folder still exists...
File makeMe = new File(folder);
int index = 0;
String master = folder;
while (makeMe.exists()) {
folder = master + (++index);
makeMe = new File(folder);
}
If you're worried about creating an infinite loop, you could place a maximum range...
int maxRange = 100;
File makeMe = new File(folder);
int index = 0;
String master = folder;
while (makeMe.exists() && index < maxRange) {
makeMe = new File(master + (++index));
}
if (index > maxRange) { // || makeMe.exists()
throw new IOException("Could not find free directory");
} else {
// All happy unicorns...
}
String folderPrefix = "folder";
int folderSuffix = 0;
File fa = new File(folderPrefix + folderSuffix);
while (fa.exists()) {
fa = new File(folderPrefix + folderSuffix++);
}
Related
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.
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);
}
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
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;
}
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();
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);
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
}
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() + ")");
}
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()
}
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.
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("."));
}
I need to identify the file numbers which are missing in a folder.
I have retrieved the files names by using the code below :
File folder = new File(FILE_PATH);
File[] listOfFiles = folder.listFiles();
for (int i = 0; i < listOfFiles.length; i++) {
if (listOfFiles[i].isFile()) {
System.out.println("File " + listOfFiles[i].getName());
} else if (listOfFiles[i].isDirectory()) {
System.out.println("Directory " + listOfFiles[i].getName());
}
}
But now after retrieving i need to find which are the file number which are missing from a file range of 1-1976 both included.
If you need just the filenames, you may use list() method. After you get all the filenames with this method, you can just check the presence of the specified filenames, like:
File parent = ...
String prefix = "xxx_", suffix = ".txt"; // for example
Set<String> files = new HashSet<>(Arrays.asList(parent.list()));
// or, as suggested by #JulienLopez:
String pattern = Pattern.quote(prefix) + "\\d+" + Pattern.quote(suffix);
Set<String> files = new HashSet<>(Arrays.asList(parent.list((dir, file) -> file.matches(pattern))));
for (int i = 1; i <= 1976; ++i) { // actually constant should be used
if (!files.contains(prefix + i + suffix)) {
System.out.format("File #%d doesn't exist%n", i);
}
}
But if you really need to check, that the file is not, for example, the directory, there's one more way to do it, by just creating the Files for every i and checking its existence:
for (int i = 1; i <= 1976; ++i) {
File file = new File(parent, prefix + i + suffix);
if (!file.isFile()) {
System.out.format("File #%d doesn't exist or is directory%n", i);
}
}
I'm not sure your structural of your file name , and what exactly on your mind with "both included". That is my idea,I hope it's a bit help for you.
String FILE_PREFIX= "your_file_prefix"; // Your file prefix. If your file is "logfile_on_20160121_0001" then the prefix is "logfile_on_20160121_"
int RANGE_MIN = 1;
int RANGE_MAX = 1976;
int fileList[] = new int[RANGE_MAX];
int directoryList[] = new int[RANGE_MAX];
// Quote your code with a bit modify from me
File folder = new File(FILE_PATH);
File[] listOfFiles = folder.listFiles();
for (int i = 0; i < listOfFiles.length; i++) {
if (listOfFiles[i].isFile()) {
System.out.println("File " + listOfFiles[i].getName());
// Added started
String tempSplitedName[] = listOfFiles[i].split(FILE_PREFIX);
if(tempSplitedName.length==2){
int seq = Integer.parseInt(tempSplitedName[2]);
if(seq>=RANGE_MIN && seq<=RANGE_MAX){
fileList[seq] = 1;
}
}
// Added ended
} else if (listOfFiles[i].isDirectory()) {
System.out.println("Directory " + listOfFiles[i].getName());
// Added started
String tempSplitedName[] = listOfFiles[i].split(FILE_PREFIX);
if(tempSplitedName.length==2){
int seq = Integer.parseInt(tempSplitedName[2]);
if(seq>=RANGE_MIN && seq<=RANGE_MAX){
directoryList[seq] = 1;
}
}
// Added ended
}
// Now you count missing files/directory, which is equal 0
for (int i=RANGE_MIN; i<=RANGE_MAX; i++){
if(fileList[i]==0) System.out.println("Missing file No." + i);
}
for (int i=RANGE_MIN; i<=RANGE_MAX; i++){
if(directoryList[i]==0) System.out.println("Missing directory No." + i);
}
I am trying to figure out how to make a string that I can use to create a file in my java program. I have tried many different ways of doing this, but nothing seems to do what I want.
Here is an example of what I am trying to do:
String fileExt = ".jpg"
for (int i = 0; i < someNumber; i ++){
fileExt = i + fileExt;
}
I want to output something like:
1.jpg
2.jpg
3.jpg
4.jpg
... and so on.
My intention is to use the changed string at every iteration in order to create a new file with it like so : File image = new File (fileExt;
List<File> files = new ArrayList<File>();
String fileExt = ".jpg"
for (int i = 0; i < someNumber; i ++){
File newfile = new File(i + fileExt);
files.add(newfile)
}
A few things here. filext should be absolute path, or the files will be created in your current directory. Keep file references in List for future use.
No matter what you do, the value of fileExt is going to be the last iteration of the loop. Maybe an array will do the trick?
String[] fileExt = new String[20];
for (int i = 0; i < fileExt.length; i++) {
fileExt[i] = i + ".jpg";
}
// view results
for (int i = 0; i < fileExt.length; i++) {
System.out.println(fileExt[i]);
}
// example
File image = new File(fileExt[0]);
I have this code in Java. The randomName() function returns a string with (unsurprisingly) a random string.
File handle = new File(file);
String parent = handle.getParent();
String lastName = "";
for (int i = 0; i < 14; i++)
{
lastName = parent + File.separator + randomName();
handle.renameTo(new File(lastName));
}
return lastName;
I have the appropriate permissions, and when I log to logcat the randomName() function does all the strings, but upon the end of the loop handle appears to have a file name of the value of the first randomName() call.
The reason this didn't work as expected is because once the file was renamed the first time, handle no longer referred to the file. That is why the subsequent rename operations failed. File represents a path name, not an actual object on disk.
This is my solution:
File handle = null;
String parent = "";
String lastName = "";
for (int i = 0; i < 14; i++)
{
if (i == 0)
{
handle = new File(file);
parent = handle.getParent();
}
else
{
lastName = parent + File.separator + randomName();
handle.renameTo(new File(lastName));
handle = new File(lastName);
}
}
In my project has 40 to 50 jar files available, It takes lot of time to find out latest version of each jar at every time. Can u any one help me to write a java program for this?
You may want to just use maven : http://maven.apache.org/
Or an other dependencies manager, like Ivy.
At the time of ant-build please call this method
public void ExpungeDuplicates(String filePath) {
Map<String,Integer> replaceJarsMap = null;
File folder = null;
File[] listOfFiles = null;
List<String> jarList = new ArrayList<String>();
String files = "";
File deleteFile = null;
Iterator<String> mapItr = null;
//String extension ="jar";
try {
folder = new File(filePath);
listOfFiles = folder.listFiles();
for (int i = 0; i < listOfFiles.length; i++) {
if (listOfFiles[i].isFile()) {
files = listOfFiles[i].getName();
jarList.add(files);
}
}
if (jarList.size() > 0) {
replaceJarsMap = PatternClassifier.findDuplicatesOrLowerVersion(jarList);
System.err.println("Duplicate / Lower Version - Total Count : "+replaceJarsMap.size());
mapItr = replaceJarsMap.keySet().iterator();
while (mapItr.hasNext()) {
String key = mapItr.next();
int repeat = replaceJarsMap.get(key);
System.out.println( key +" : "+repeat);
for (int i = 0; i <repeat; i++) {
deleteFile = new File(filePath + System.getProperty ("file.separator")+key);
try{
if (deleteFile != null && deleteFile.exists()){
if(deleteFile.delete()){
System.err.println(key +" deleted");
}
}
}catch (Exception e) {
}
}
}
}
} catch (Exception e) {
// TODO: handle exception
}
}
You only need to give the path of your Lib to this function.This method will find all the duplicate or lower version of of file.
And the crucial function is given below...Which finds out the duplicates from the list of files you provided.
public static Map<String,Integer> findDuplicatesOrLowerVersion(List<String> fileNameList) {
List<String> oldJarList = new ArrayList<String>();
String cmprTemp[] = null;
boolean match = false;
String regex = "",regexFileType = "",verInfo1 = "",verInfo2 = "",compareName = "",tempCompareName = "",tempJarName ="";
Map<String,Integer> duplicateEntryMap = new HashMap<String, Integer>();
int count = 0;
Collections.sort(fileNameList, Collections.reverseOrder());
try{
int size = fileNameList.size();
for(int i = 0;i<size;i++){
cmprTemp = fileNameList.get(i).split("[0-9\\._]*");
for(String s : cmprTemp){
compareName += s;
}
regex = "^"+compareName+"[ajr0-9_\\-\\.]*";
regexFileType = "[0-9a-zA-Z\\-\\._]*\\.jar$";
if( fileNameList.get(i).matches(regexFileType) && !oldJarList.contains(fileNameList.get(i))){
for(int j = i+1 ;j<size;j++){
cmprTemp = fileNameList.get(j).split("[0-9\\._]*");
for(String s : cmprTemp){
tempCompareName += s;
}
match = (fileNameList.get(j).matches(regexFileType) && tempCompareName.matches(regex));
if(match){
cmprTemp = fileNameList.get(i).split("[a-zA-Z\\-\\._]*");
for(String s : cmprTemp){
verInfo1 += s;
}
verInfo1 += "000";
cmprTemp = fileNameList.get(j).split("[a-zA-Z\\-\\._]*");
for(String s : cmprTemp){
verInfo2 += s;
}
verInfo2 += "000";
int length = 0;
if(verInfo1.length()>verInfo2.length()){
length = verInfo2.length();
}else{
length = verInfo1.length();
}
if(Long.parseLong(verInfo1.substring(0,length))>=Long.parseLong(verInfo2.substring(0,length))){
count = 0;
if(!oldJarList.contains(fileNameList.get(j))){
oldJarList.add(fileNameList.get(j));
duplicateEntryMap.put(fileNameList.get(j),++count);
}else{
count = duplicateEntryMap.get(fileNameList.get(j));
duplicateEntryMap.put(fileNameList.get(j),++count);
}
}else{
tempJarName = fileNameList.get(i);
}
match = false;verInfo1 = "";verInfo2 = "";
}
tempCompareName = "";
}
if(tempJarName!=null && !tempJarName.equals("")){
count = 0;
if(!oldJarList.contains(fileNameList.get(i))){
oldJarList.add(fileNameList.get(i));
duplicateEntryMap.put(fileNameList.get(i),++count);
}else{
count = dupl icateEntryMap.get(fileNameList.get(i));
duplicateEntryMap.put(fileNameList.get(i),++count);
}
tempJarName = "";
}
}
compareName = "";
}
}catch (Exception e) {
e.printStackTrace();
}
return duplicateEntryMap;
}
What findDuplicatesOrLowerVersion(List fileNameList) function task - Simply it found the duplicates and passting a map which contains the name of the file and number of time the lower version repeats.
Try this. The remaining file exist in the folder should be latest or files with out duplicates.Am using this for finding the oldest files.on the basis of that it will find the old and delete it.
This am only checking the name..Futher improvement you can made.
Where PatternClassifier is a class which contains the second method given here.