delete a folder in java - java

The folder I need to delete is one that is created from my program. The directory is not the same on every pc so the folder code I am using is
userprofile+"\\Downloads\\Software_Tokens"
There will be files in, so I guess i need to recursively delete it. I looked at some samples for that here but it never accepts my path. The path works fine in the code as an environmental variable, because i added code for it
static String userprofile = System.getenv("USERPROFILE");
so can someone just show me the code with my path plugged please?

If your directory is not empty, you may use the Apache Commons IO API's method deleteDirectory(File file) :
String toDelete = userprofile + File.separator + "Downloads" +
File.separator + "Software_Tokens";
FileUtils.deleteDirectory(new File(toDelete));
Be careful with the / or \ that are system dependent and use File.separator instead.

If you don't want to use apache library ! You can do it recursively.
String directory = userprofile + File.separator + "Downloads" + File.separator + "Software_Tokens";
if (!directory.exists()) {
System.out.println("Directory does not exist.");
System.exit(0);
} else {
try {
delete(directory);
} catch (IOException e) {
e.printStackTrace();
System.exit(0);
}
}
System.out.println("Done");
}
public static void delete(File file)
throws IOException {
if (file.isDirectory()) {
//directory is empty, then delete it
if (file.list().length == 0) {
file.delete();
System.out.println("Directory is deleted : " + file.getAbsolutePath());
} else {
//list all the directory contents
String files[] = file.list();
for (String temp: files) {
//construct the file structure
File fileDelete = new File(file, temp);
//recursive delete
delete(fileDelete);
}
//check the directory again, if empty then delete it
if (file.list().length == 0) {
file.delete();
System.out.println("Directory is deleted : " + file.getAbsolutePath());
}
}
} else {
//if file, then delete it
file.delete();
System.out.println("File is deleted : " + file.getAbsolutePath());
}

Related

File.createTempFile in Java getting Incompatible type error

Till now my code works fine where I am creating file in temporary directory and processing it.
But now I am trying to provide specific directory where I actually want to create xml file. So in method createTmpXmlFile
private static Path createTmpXmlFile(final String prefix) {
try {
log.info("Creating temporary file {}{}", prefix, XML_SUFFIX);
return Files.createTempFile(Paths.get(gleifZipFile), prefix, XML_SUFFIX);
} catch (IOException e) {
throw new IllegalStateException("Could not create tmp file at " + prefix + XML_SUFFIX + ". ", e);
}
}
I changed from
return Files.createTempFile(prefix, XML_SUFFIX);
to
return File.createTempFile(prefix, XML_SUFFIX, "/tmp/in");
and I get following error:
java: incompatible types: java.lang.String cannot be converted to java.io.File.
If I change the logic here then its affecting other method that are calling createTmpXmlFile method.
I really don't understand how to resolve this issue. Below is my code:
#Slf4j
public class InputCS implements Runnable {
public static final String XML_SUFFIX = ".xml";
#Value("${gleifdataimporter.file.dir}")
private String gleifZipFile;
private void processleifZipFile() {
final AtomicBoolean isInsideLeiRecord = new AtomicBoolean();
isInsideLeiRecord.set(false);
final StringBuilder currentLeiRecordXml = new StringBuilder();
try (FileSystem zipFs = FileSystems.newFileSystem(jobRunner.getInputZipPath(), null)) {
Path tmpXMLPath = xmlFileFromLeiZipFile(zipFs);
try (Stream<String> lines = Files.lines(tmpXMLPath)) {
AtomicInteger processedLinesCounter = new AtomicInteger();
AtomicInteger currentLineNumber = new AtomicInteger();
lines.sequential().forEach(handleLineAndIncrementLineNumber(isInsideLeiRecord, currentLeiRecordXml, processedLinesCounter, currentLineNumber));
log.info("{} lines of XML file inside LEIF input ZIP file {} processed.", processedLinesCounter.get(), jobRunner.getInputZipPath());
}catch (IOException e) {
throw new IllegalStateException("Problem reading input file at " + jobRunner.getInputZipPath() + ".", e);
} finally {
Files.delete(tmpXMLPath);
}
} catch (IOException e) {
throw new IllegalStateException("Problem reading input file at " + jobRunner.getInputZipPath() + ".", e);
}
}
private Path xmlFileFromLeiZipFile(FileSystem zipFs) { //extracts the xml file from zip file
log.info("Input file {} exists: {}", jobRunner.getInputZipPath(), Files.exists(jobRunner.getInputZipPath()));
Path tmpXmlPath = createTmpXmlFile("leif__" + System.currentTimeMillis());
for (Path rootDir : zipFs.getRootDirectories()) {
try (Stream<Path> files = treeAt(rootDir)) {
log.info("Trying to extract LEIF XML file from ZIP file into {}.", tmpXmlPath);
final Path xmlFileInsideZip = files
.filter(isNotADir())
.filter(Files::isRegularFile)
.findFirst()
.orElseThrow(() -> new IllegalStateException("No file found in LEI ZIP file."));
log.info("Path to LEIF XML file inside ZIP file: {}.", xmlFileInsideZip);
return copyReplacing(xmlFileInsideZip, tmpXmlPath);
}
}
throw new IllegalStateException("No file found in LEI ZIP file " + jobRunner.getInputZipPath() + ".");
}
private static Path createTmpXmlFile(final String prefix) {
try {
log.info("Creating temporary file {}{}", prefix, XML_SUFFIX);
return Files.createTempFile(Paths.get(gleifZipFile), prefix, XML_SUFFIX);
} catch (IOException e) {
throw new IllegalStateException("Could not create tmp file at " + prefix + XML_SUFFIX + ". ", e);
}
}
#NotNull
private static Path copyReplacing(Path from, Path to) {
requireNonNull(from, "Trying to copy from a path, which is null to path " + to + "."); //trying to copy file where no xml file exist in root directory
requireNonNull(to, "Trying to copy from path " + from + " to a path, which is null.");
try {
return Files.copy(from, to, REPLACE_EXISTING);
} catch (IOException e) {
throw new IllegalStateException("Cannot copy from " + from + " to " + to + ". ", e);
}
}
}
As suggested by Slaw, use Files#createTempFile(Path,String,String,FileAttribute...) to specify the directory to create temp file.
Use Paths#get(String,String...) for java 7 or 8, or Path#of(String,String...) for java 11 or later to convert String to Path. Further reading: Paths.get vs Path.of
private static Path createTmpXmlFile(final String prefix) {
try {
// Java 11 or later
// return Files.createTempFile(Path.of("/tmp/in"), prefix, XML_SUFFIX);
// Java 8
return Files.createTempFile(Paths.get("/tmp/in"), prefix, XML_SUFFIX);
} catch (IOException e) {
throw new IllegalStateException("Could not create tmp file at " + prefix + XML_SUFFIX + ". ", e);
}
}
File.createTempFile is expecting a File object as third parameter. Just wrap your "/tmp/in" into a File
=> return File.createTempFile(prefix, XML_SUFFIX, new File("/tmp/in")); and you should be good to go.
so you can do:
File.createTempFile("prefix", "suffix", new File("/tmp/in"));
Or using NIO (recommended)
Files.createTempFile(Paths.get("/tmp/in"), "prefix", "suffix");

Trouble copying file in Android

My problem is not How to make a copy of a File in Android, My problem is why it fails to make a copy.
After my app downloads a file am trying to copy it to another folder (The end user can save the file in several folder, that why i download once and copy to the rest). I do have the origin file path like:
/storage/emulated/0/MyAppFolder/FolderCreatedByUser1/theFile.pdf
And am trying to copy it to
/storage/emulated/0/MyAppFolder/FolderCreatedByUser2/
With this code (Code improved by Robert Nekic):
public static boolean copyFile(File src, File[] dst) {
boolean result = true;
if (src.exists()) {
String srcName = src.getName();
for (File file : dst) {
String to = file.getPath();
try {
File destination = new File(to, srcName);
if (destination.createNewFile()) {
FileChannel srcChnl = new FileInputStream(src).getChannel();
FileChannel dstChnl = new FileOutputStream(destination).getChannel();
dstChnl.transferFrom(srcChnl, 0, srcChnl.size());
srcChnl.close();
dstChnl.close();
} else {
result = false;
System.out.println("Unable to create destination " + destination.getPath());
}
} catch (Exception e) {
result = false;
System.out.println(e.getMessage());
break;
}
}
} else {
result = false;
System.out.println("File " + src.getPath() + " doesn't exist.");
}
return result;
}
The file exist, but am keep getting errors when copying it to the destiny file like:
/storage/emulated/0/MyAppFolder/FolderCreatedByUser2/theFile.pdf: open failed: ENOENT (No such file or directory)
It fails in both streams, when trying to open the src file and/or destination file:
FileChannel srcChnl = new FileInputStream(src).getChannel();
FileChannel dstChnl = new FileOutputStream(destination).getChannel();
Permission to write are granted. The destination folders are created previously to the download of the file, the user can't select a destination if the directory isn't created.
destination = new File(to, srcName); creates a new File instance but does not create the underlying file. You can verify by checking destination.exists(). I believe all you need is:
destination = new File(to, srcName);
destination.createNewFile();
Also, your src path string manipulation and stuff in the first half of your code seems unnecessary and might be introducing an error that could be resolved with something more concise:
public static boolean copyFile(File src, File[] dst) {
boolean result = true;
if (src.exists()) {
String srcName = src.getName();
for (File file : dst) {
String to = file.getPath();
try {
File destination = new File(to, srcName);
if (destination.createNewFile()) {
FileChannel srcChnl = new FileInputStream(src).getChannel();
FileChannel dstChnl = new FileOutputStream(destination).getChannel();
dstChnl.transferFrom(srcChnl, 0, srcChnl.size());
srcChnl.close();
dstChnl.close();
} else {
result = false;
System.out.println("Unable to create destination " + destination.getPath());
}
} catch (Exception e) {
result = false;
System.out.println(e.getMessage());
break;
}
}
} else {
result = false;
System.out.println("File " + src.getPath() + " doesn't exist.");
}
return result;
}

How to increment the number within the file name each time a new file is created?

Hi there I am currently writing a method in Java where I am trying to create new files but I need those files not to be of the same name, but rather of incrementing name values, like so:
/Users/Myself/Desktop/myFile0.xml
/Users/Myself/Desktop/myFile1.xml
/Users/Myself/Desktop/myFile2.xml
/Users/Myself/Desktop/myFile3.xml
So I have tried to do the following in my code, but I do not understand why when I call the file within the for each loop ( to create a new one) the number does not increment?
public void pickFolder() throws Exception {
chooserFolder.setDialogTitle("Specify your save location");
chooserFolder.setDialogType(JFileChooser.SAVE_DIALOG);
int numbers = 0;
chooserFolder.setSelectedFile(new File("myFile" + numbers++ + ".xml"));
chooserFolder.setFileFilter(new FileNameExtensionFilter("xml file", "xml"));
int userSelection = chooserFolder.showSaveDialog(null);
if (userSelection == JFileChooser.APPROVE_OPTION) {
for (File file : files) {
chooserFolder.setSelectedFile(new File(chooserFolder.getSelectedFile().getAbsolutePath()));
fileToSave = chooserFolder.getSelectedFile();
if (fileToSave.createNewFile()) {
System.out.println("File is created!");
fileToSave = chooserFolder.getSelectedFile();
} else {
JOptionPane.showMessageDialog(null, "File already exists.");
}
System.out.println("Save as file: " + fileToSave.getAbsolutePath());
}
Any help would be greatly appreciated, Thank you!
Your numbers variable should be static;
public static int numbers = 0;
public void pickFolder() throws Exception {
chooserFolder.setDialogTitle("Specify your save location");
chooserFolder.setDialogType(JFileChooser.SAVE_DIALOG);
chooserFolder.setSelectedFile(new File("myFile" + numbers++ + ".xml"));
chooserFolder.setFileFilter(new FileNameExtensionFilter("xml file", "xml"));
int userSelection = chooserFolder.showSaveDialog(null);
if (userSelection == JFileChooser.APPROVE_OPTION) {
for (File file : files) {
chooserFolder.setSelectedFile(new File(chooserFolder.getSelectedFile().getAbsolutePath()));
fileToSave = chooserFolder.getSelectedFile();
if (fileToSave.createNewFile()) {
System.out.println("File is created!");
fileToSave = chooserFolder.getSelectedFile();
} else {
JOptionPane.showMessageDialog(null, "File already exists.");
}
System.out.println("Save as file: " + fileToSave.getAbsolutePath());
}
That way whenever you call pickFolder()-either you create a new instance or use the same instance- your numbers variable stays the same for every instance.
That will be because you are appending it to a string "something" + 1 would be string concatenation in java.
Try something like this :
chooserFolder.setSelectedFile(new File("myFile" + (numbers++) + ".xml"));
This will make sure the number is incremented and then replaced with corresponding value.

How to delete a folder containing other folders in Java? [duplicate]

This question already has answers here:
Delete directories recursively in Java
(26 answers)
Closed 9 years ago.
Here is a code I tried:
import java.io.*;
public class file03 {
public static void main(String[] args) {
File f1 = new File("C:/tempo1/tempo");
f1.mkdirs();
File f2 = new File("C:/test");
if(!f2.exists()) {
f2.mkdir();
}
f1 = new File("C:/tempo1/kempo");
f1.mkdirs();
f1 = new File("C:/tempo1");
String[] t = {};
if(f1.exists()) {
t = f1.list();
System.out.println(t.length + " files found");
}
for(int i = 0; i < t.length; i++) {
System.out.println(t[i]);
}
try {
Thread.sleep(3000);
}
catch(Exception e) {}
f2.delete();
f2 = new File("C:/tempo1/test.txt");
try {
f2.createNewFile();
}
catch(Exception e) {}
try {
Thread.sleep(7000);
}
catch(Exception e) {}
File f3 = new File("C:/tempo1/renametesting.txt");
f2.renameTo(f3);
try {
Thread.sleep(5000);
}
catch(Exception e) {}
f3 = new File("C:/tempo1");
f3.delete();
}
}
what I noticed was that while the folder test gets deleted, the folder tempo1 doesn't get deleted. Is it because it contains other folders and files? If so, how can I delete it?
I am using BlueJ IDE.
A folder can not be deleted until all files of that folder are deleted.
First delete all files from that folder then delete that folder
This is code for deleting a folder..
You need to pass the path of the folder only
public static void delete(File file)
throws IOException {
if (file.isDirectory()) {
//directory is empty, then delete it
if (file.list().length == 0) {
file.delete();
// System.out.println("Directory is deleted : "+ file.getAbsolutePath());
} else {
//list all the directory contents
String files[] = file.list();
for (String temp : files) {
//construct the file structure
File fileDelete = new File(file, temp);
//recursive delete
delete(fileDelete);
}
//check the directory again, if empty then delete it
if (file.list().length == 0) {
file.delete();
// System.out.println("Directory is deleted : " + file.getAbsolutePath());
}
}
} else {
//if file, then delete it
file.delete();
// System.out.println("File is deleted : " + file.getAbsolutePath());
}
}
public class DeleteFolder {
/**
* Delete a folder and all content folder & files.
* #param folder
*/
public void rmdir(final File folder) {
if (folder.isDirectory()) { //Check if folder file is a real folder
File[] list = folder.listFiles(); //Storing all file name within array
if (list != null) { //Checking list value is null or not to check folder containts atlest one file
for (int i = 0; i < list.length; i++) {
File tmpF = list[i];
if (tmpF.isDirectory()) { //if folder found within folder remove that folder using recursive method
rmdir(tmpF);
}
tmpF.delete(); //else delete file
}
}
if (!folder.delete()) { //if not able to delete folder print message
System.out.println("can't delete folder : " + folder);
}
}
}
}
To delete folder having files , no need of loops or recursive search. You can directly use:
FileUtils.deleteDirectory(<File object of directory>);
This function will delete the folder and all files in it
You can use the commons io library FileUtils class :
http://commons.apache.org/proper/commons-io/apidocs/org/apache/commons/io/FileUtils.html#deleteDirectory(java.io.File)
"Deletes a directory recursively."

Java delete and rename file issue

Method below has function to simply move files from the "working" to the "move" directory which paths it receives through the method call. It all works, but for the case when file name has name with two extensions (like .xml.md5) where the .renameTo method returns false. Is there a way to alter the below code so it would work regardless of the OS that it's run on. (Currently it is the Windows)
public void moveToDir(String workDir, String moveDir) throws Exception {
File tempFile = new File(workDir);
File[] filesInWorkingDir = tempFile.listFiles();
for (File file : filesInWorkingDir) {
System.out.println(file.getName());
if (new File(moveDir + File.separator + file.getName()).exists())
new File(moveDir + File.separator + file.getName()).delete();
System.out.println(moveDir + File.separator + file.getName());
Boolean renameSuccessful = file.renameTo(new File(moveDir + File.separator + file.getName()));
if (!renameSuccessful) throw new Exception("Can't move file to " + moveDir +": " + file.getPath());
}
}
I have simplified your code and added a check if delete was successful. Try it.
public void moveToDir(String workDir, String moveDir) {
for (File file : new File(workDir).listFiles()) {
System.out.println(file.getName());
final File toFile = new File(moveDir, file.getName());
if (toFile.exists() && !toFile.delete())
throw new RuntimeException("Cannot delete " + toFile);
System.out.println(toFile);
if (!file.renameTo(toFile))
throw new RuntimeException(
"Can't move file to " + moveDir +": " + file.getPath());
}
}

Categories

Resources