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
}
Related
I am using this method to generate some turtle files .ttl in a sub-directory of my project:
public static void write(int id, int depth){
try {
FileWriter fw = null;
switch (getName()){
case ("KG1"):
fw = new FileWriter("WWW/KG1/" + depth + "/" + id + ".ttl");
break;
case ("KG2"):
fw = new FileWriter("WWW/KG2/" + depth + "/" + id + ".ttl");
}
// Write something
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
But I am having this exception when I have put my project in Ubuntu (it is still working fine in Windows) in the java class FileWriter:
java.io.FileNotFoundException: /WWW/KG1/2/0.ttl (No such file or directory)
I am using Eclipse Neon for both OSs, but it seems that Ubuntu is not happy about it.
Here is what I have tried so far:
Adding write permissons to ALL files and directories under the main project directory
Using absolute path instead of relative path, by using System.getProperty("usr.dir"), and plotting all the path string I am giving to FileWriter, but it does not work.
Any advice?
Thanks!
You can make things easier for yourself by using Path and File objects. Here is a version that optionally creates the wanted directory if it doesn't exist
Path path = Paths.get("WWW", "KG1", String.valueOf(depth));
try {
Files.createDirectories(path);
FileWriter fw = new FileWriter(new File(path.toFile(), id + ".ttl"));
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
Note that I intentionally skipped the switch to simplify the answer
I would try using File.separator and make sure the parent directory exists.
Here is an example (may have syntax issues).
final String WWW = "WWW";
final String KG1 = "KG1";
final String KG2 = "KG2";
final String extension = ".ttl";
int id = 1;
int depth = 1;
String filePath = "." // current dir
+ File.separator
+ WWW
+ File.separator
+ KG1
+ File.separator
+ depth
+ File.separator
+ id
+ extension;
File file = new File(filePath);
// make sure parent dir exists (else created)
file.getParentFile().mkdirs();
FileWriter writer = new FileWriter(file);
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 + ")";
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.
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.
I have a method that get text from a JTextArea, create a file and write text on it as code below:
public void createTxt() {
TxtFilter txt = new TxtFilter();
JFileChooser fSave = new JFileChooser();
fSave.setFileFilter(txt);
int result = fSave.showSaveDialog(this);
if(result == JFileChooser.APPROVE_OPTION) {
File sFile = fSave.getSelectedFile();
FileFilter selectedFilter = fSave.getFileFilter();
String file_name = sFile.getName();
String file_path = sFile.getParent();
try{
if(!sFile.exists()) {
sFile.createNewFile();
BufferedWriter out = new BufferedWriter(new FileWriter(sFile));
out.write(jTextArea1.getText());
out.close();
JOptionPane.showMessageDialog(null, "Warning file • " + file_name + " • created succesfully in \n" + file_path);
} else {
String message = "File • " + file_name + " • already exist in \n" + file_path + ":\n" + "Do you want to overwrite?";
String title = "Warning";
int reply = JOptionPane.showConfirmDialog(null, message, title, JOptionPane.YES_NO_OPTION);
if(reply == JOptionPane.YES_OPTION){
sFile.delete();
sFile.createNewFile();
BufferedWriter out = new BufferedWriter(new FileWriter(sFile));
out.write(jTextArea1.getText());
out.close();
JOptionPane.showMessageDialog(null, "File • " + file_name + " • overwritten succesfully in \n" + file_path);
}
}
}
catch(IOException e) {
System.out.println("Error");
}
}
}
and a txt file filter
public class TxtFilter extends FileFilter{
#Override
public boolean accept(File f){
return f.getName().toLowerCase().endsWith(".txt")||f.isDirectory();
}
#Override
public String getDescription(){
return "Text files (*.txt)";
}
}
The file filter for txt works fine but what I want is to add ".txt" extension when I type file name.
How to I have to modify my code?
I just use this
File fileToBeSaved = fileChooser.getSelectedFile();
if(!fileChooser.getSelectedFile().getAbsolutePath().endsWith(suffix)){
fileToBeSaved = new File(fileChooser.getSelectedFile() + suffix);
}
UPDATE
You pointed me out that the check for existing files doesn't work. I'm sorry, I didn't think of it when I suggested you to replace the BufferedWriter line.
Now, replace this:
File sFile = fSave.getSelectedFile();
with:
File sFile = new File(fSave.getSelectedFile()+".txt");
With this replacement, it isn't now needed to replace the line of BufferedWriter, adding .txt for the extension. Then, replace that line with the line in the code you posted (with BufferedWriter out = new BufferedWriter(new FileWriter(sFile)); instead of BufferedWriter out = new BufferedWriter(new FileWriter(sFile+".txt"));).
Now the program should work as expected.
I forgot to mention that you have to comment the line:
sFile.createNewFile();
In this way, you're creating an empty file, with the class File.
Just after this line, there is: BufferedWriter out = new BufferedWriter(new FileWriter(sFile));.
With this line, you are creating again the same file. The writing procedure is happening two times! I think it's useless to insert two instructions that are doing the same task.
Also, on the BufferedWriter constructor, you can append a string for the file name (it isn't possible on File constructor), that's the reason why I added +".txt" (the extension) to sFile.
This is a utility function from one of my programs that you can use instead of JFileChooser.getSelectedFile, to get the extension too.
/**
* Returns the selected file from a JFileChooser, including the extension from
* the file filter.
*/
public static File getSelectedFileWithExtension(JFileChooser c) {
File file = c.getSelectedFile();
if (c.getFileFilter() instanceof FileNameExtensionFilter) {
String[] exts = ((FileNameExtensionFilter)c.getFileFilter()).getExtensions();
String nameLower = file.getName().toLowerCase();
for (String ext : exts) { // check if it already has a valid extension
if (nameLower.endsWith('.' + ext.toLowerCase())) {
return file; // if yes, return as-is
}
}
// if not, append the first extension from the selected filter
file = new File(file.toString() + '.' + exts[0]);
}
return file;
}
I've done this function for this purpose :
/**
* Add extension to a file that doesn't have yet an extension
* this method is useful to automatically add an extension in the savefileDialog control
* #param file file to check
* #param ext extension to add
* #return file with extension (e.g. 'test.doc')
*/
private String addFileExtIfNecessary(String file,String ext) {
if(file.lastIndexOf('.') == -1)
file += ext;
return file;
}
Then you can use the function for example in this way :
JFileChooser fS = new JFileChooser();
String fileExt = ".txt";
addFileExtIfNecessary(fS.getSelectedFile().getName(),fileExt)