How to correct File .exists() method [duplicate] - java

This question already has answers here:
Is there a difference between x++ and ++x in java?
(18 answers)
Closed 1 year ago.
I am using the .exists() method to make sure a file does not exists and if it does, it adds a number to the file. However, it is not working and creating the file using the original filename and essentially overwriting the previous when creating another one.
This is my code:
int count = 1;
String name = "myFileName" + count;
String path = "/pathway/";
String ext = ".txt";
File file = new File(path + name + ext);
if (file.exists()) {
System.out.println("file found!");
name = "myFileName" + (count++);
file = new File(path + name + ext);
}
System.out.println("wrote file: " + name);
The output is this whenever I run it over again:
[1:47:40:359] wrote file: myFileName1
[1:47:40:361] wrote file: myFileName1

Your mistake is the count++. The postfixed ++ operator first 'returns' the value and then increments it. You need to first increment, and then return. Do this with the prefixed ++ operator: ++count
A while loop should help, to ensure, that you create a new file, even if the previous existed, even if a second or third also exists.
int count = 1;
String name = "myFileName" + count;
String path = "/pathway/";
String ext = ".txt";
File file = new File(path + name + ext);
while (file.exists()) {
System.out.println("file found!");
name = "myFileName" + (++count);
file = new File(path + name + ext);
}
System.out.println("wrote file: " + name);

Related

Java create multiple new files

I read this question here How to create a file in a directory in java?
I have a method that creates a QR Code. The method is called several times, depends on user input.
This is a code snippet:
String filePath = "/Users/Test/qrCODE.png";
int size = 250;
//tbd
String fileType = "png";
File myFile = new File(filePath);
The problem: If the user types "2" then this method will be triggered twice.
As a result, the first qrCODE.png file will be replaced with the second qrCODE.png, so the first one is lost.
How can I generate more than one qr code with different names, like qrCODE.png and qrCODE(2).png
My idea:
if (!myFile.exists()) {
try {
myFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
Any tips?
EDIT: I solved it by using a for loop and incrementing the number in the filename in every loop step.
You can create more files eg. like follows
int totalCount = 0; //userinput
String filePath = "/Users/Test/";
String fileName= "qrCODE";
String fileType = "png";
for(int counter = 0; counter < totalCount; counter++){
int size = 250;
//tbd
File myFile = new File(filePath+fileName+counter+"."+fileType);
/*
will result into files qrCODE0.png, qrCODE1.png, etc..
created at the given location
*/
}
Btw to add check if file exists is also good point.
{...}
if(!myFile.exists()){
//file creation
myFile.createNewFile()
}else{
//file already exists
}
{...}
Your idea of solving the problem is a good one. My advice is to break up the filePath variable into a few variables in order to manipulate the file name easier. You can then introduce a fileCounter variable that will store the number of files created and use that variable to manipulate the name of the file.
int fileCounter = 1;
String basePath = "/Users/Test/";
String fileName = "qrCODE";
String fileType = ".png";
String filePath = basePath + fileName + fileType;
File myFile = new File(filePath);
You can then check if the file exists and if it does you just give a new value to the filePath variable and then create the new file
if(myFile.exists()){
filePath = basePath + fileName + "(" + ++fileCounter + ")" + fileType;
myFile = new File(filePath);
}
createFile(myFile);
And you're done!
You can check /Users/Test direcroty before create file.
String dir = "/Users/Test";
String pngFileName = "qrCode";
long count = Files.list(Paths.get(dir)) // get all files from dir
.filter(path -> path.getFileName().toString().startsWith(pngFileName)) // check how many starts with "qrCode"
.count();
pngFileName = pngFileName + "(" + count + ")";

File already existing - repeated name

i am creating a file and when i create that file, i check if it already exists. If it already exists, i want to create it with the same name, but with the (1) after it. I am able to do that and here is the code :
File apkReceived = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/"+receivedApkName + ".apk");
if(apkReceived.exists()){
apkReceived=new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/"+receivedApkName + "(1)"+".apk");
}
byte[] buffer = new byte [8192];
FileOutputStream fos=new FileOutputStream(apkReceived);
then it would continue... (i am writing things on the file).
This works but the problem is that in this situation :
FileTest.apk
FileTest(1).apk
If I receive another Filetest, it will sub my FileTest(1), since it will create it again.
A solution for this would be to check if the file exists again, but then i would have to be doing that for ever.
My goal would be to create (1) and then (2) , etc.
Does any one of you know how to do this ?
EDIT: Obviously i could use a cicle to check it. The problem is on how to get the (1) and then the (2) and don't get the (1)(2)
To avoid reinventing the wheel I suggest using Timestamp it hardly ever will have collisions.
java.util.Date date= new java.util.Date();
Timestamp tstamp = new Timestamp(date.getTime());
File apkReceived = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/"+receivedApkName + tstamp + ".apk");
Do Something like this
File apkReceived = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/"+receivedApkName + ".apk");
if(apkReceived.exists()){
int new_int_postfix;
//Below _MAX is max numbers of file eg. _MAX = 100
for(int i = 1; i < _MAX; i++) {
apkReceived = = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/"+receivedApkName +"("+ i +")"+".apk");
if(!apkReceived.exists()) {
String []name_without_pre = receivedApkName.split("\\(");
receivedApkName = name_without_pre[0];
new_int_postfix = i;
break;
}
}
apkReceived = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/"+receivedApkName + "("+new_int_postfix+")"+".apk");
}
byte[] buffer = new byte [8192];
FileOutputStream fos=new FileOutputStream(apkReceived);
Some pseudocode to get you started:
Fetch a list of all files in the directory
For the one you want to copy: check if you already have one or more copies
If you already have "file_(n)"; use "file_(n+1)" as new filename.
Obviously: you should clarify your requirements on the "maximum" n you want to allow; and what to happen when n copies were created; and another is asked for.
If you only store that one type of file in your directory you can do:
File folder = new File("your/path");
File[] listOfFiles = folder.listFiles();
count the size and size + 1 for your next filename.
you can also separate each file with similiar filename on their own directory.
try this
String filename =Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/"+receivedApkName + ".apk";
File f = new File(filename);
String extension = ".apk";
int g = 0;
while(f.exists()) {
int i = f.lastIndexOf('.');
if (i > 0)
{ extension = fileName.substring(i+1); }
f.renameTo(f.getPath() + "\" + (f.getName() + g) + "." + extension)
}

Create multiple copies of a singlle file in java

i have a fileserver and client and want to rename files, if they already exists in downloadfolder. what is the best way to do that? I tried that code but it always create one copy and the next copy overwrites the first one.
File f = new File(FILE_DIR + fileName);
if(f.exists()) {
System.out.print("file already exists");
fileName = "copy_of_" + fileName;
}
In your class you declare :
private static int X = 0;
and then change the code to this:
File f = new File(FILE_DIR + fileName);
if(f.exists()) {
System.out.print("file already exists");
fileName = "copy_of_ " + X + fileName;
x++;
}
so everytime the x will increase by 1, (x++), so they will have different names.

How to sequentially numbering files rather than overwriting them when moving

I am writing a code that could move the file from one directory to another, but I have an issue with having a file that have the same name, so I decided to number them as I don't want to overwrite them.
Assume I have file a.txt, I succeed to move to move the file with the same name then call it a_1.txt, but I am wondering what I can do if I have again a.txt?
Moreover, I feel my code is not efficient and it will be appreciated if you help me to enhance it.
My code is:
/*
* Method to move a specific file from directory to another
*/
public static void moveFile(String source, String destination) {
File file = new File(source);
String newFilePath = destination + "\\" + file.getName();
File newFile = new File(newFilePath);
if (!newFile.exists()) {
file.renameTo(new File(newFilePath));
} else {
String fileName = FilenameUtils.removeExtension(file.getName());
String extention = FilenameUtils.getExtension(file.getPath());
System.out.println(fileName);
if (isNumeric(fileName.substring(fileName.length() - 1))) {
int fileNum = Integer.parseInt(fileName.substring(fileName.length() - 1));
file.renameTo(new File(destination + "\\" + fileName + ++fileNum + "." + extention));
} else {
file.renameTo(new File(destination + "\\" + fileName + "_1." + extention));
}
}//End else
}
From the main, I called it as the following (Note that ManageFiles is the class name that the method exist in):
String source = "L:\\Test1\\Graduate.JPG";
String destination = "L:\\Test2";
ManageFiles.moveFile(source, destination);
You can use this logic:
If the file already exists in the destination, you add "(1)" to the file name (before the extension). But then you ask me: what if there's already a file with "(1)"? Then you use (2). If there's already one with (2) too, you use (3), and so on.
You can use a loop to acomplish this:
/*
* Method to move a specific file from directory to another
*/
public static void moveFile(String source, String destination) {
File file = new File(source);
String newFilePath = destination + "\\" + file.getName();
File newFile = new File(newFilePath);
String fileName;
String extention;
int fileNum;
int cont;
if (!newFile.exists()) {
file.renameTo(new File(newFilePath));
} else {
cont = 1;
while(newFile.exists()) {
fileName = FilenameUtils.removeExtension(file.getName());
extention = FilenameUtils.getExtension(file.getPath());
System.out.println(fileName);
newFile = new File(destination + "\\" + fileName + "(" + cont++ + ")" + extention);
}
newFile.createNewFile();
}//End else
}

Add index to filename for existing file (file.txt => file_1.txt)

I want to add an index to a filename if the file already exists, so that I don't overwrite it.
Like if I have a file myfile.txt and same time myfile.txt exists in destination folder - I need to copy my file with name myfile_1.txt
And same time if I have a file myfile.txt, but destintation folder contains myfile.txt and myfile_1.txt - generated filename has to be myfile_2.txt
So the functionality is very similar to the creation of folders in Microsoft operating systems.
What's the best approach to do that?
Using commons-io:
private static File getUniqueFilename( File file )
{
String baseName = FilenameUtils.getBaseName( file.getName() );
String extension = FilenameUtils.getExtension( file.getName() );
int counter = 1
while(file.exists())
{
file = new File( file.getParent(), baseName + "-" + (counter++) + "." + extension );
}
return file
}
This will check if for instance file.txt exist and will return file-1.txt
You might also benefit from using the apache commons-io library. It has some usefull file manipulation methods in class FileUtils and FilenameUtils.
Untested Code:
File f = new File(filename);
String extension = "";
int g = 0;
int i = f.lastIndexOf('.');
extension = fileName.substring(i+1);
while(f.exists()) {
if (i > 0)
{ f.renameTo(f.getPath() + "\" + (f.getName() + g) + "." + extension); }
else
{ f.renameTo(f.getPath() + "\" + (f.getName() + g)); }
g++;
}
Try this link partly answers your query.
https://stackoverflow.com/a/805504/1961652
DirectoryScanner scanner = new DirectoryScanner();
scanner.setIncludes(new String[]{"**/myfile*.txt"});
scanner.setBasedir("C:/Temp");
scanner.setCaseSensitive(false);
scanner.scan();
String[] files = scanner.getIncludedFiles();
once you have got the correct set of files, append a proper suffix to create a new file.

Categories