Recursively Deleting a Directory - java

I have this section of code:
public static void delete(File f) throws IOException
{
if (f.isDirectory())
{
for (File c : f.listFiles())
{
delete(c);
}
}
else if (!f.delete())
{
throw new FileNotFoundException("Failed to delete file: " + f);
}
}
public static void traverseDelete(File directory) throws FileNotFoundException, InterruptedException
{
//Get all files in directory
File[] files = directory.listFiles();
for (File file : files)
{
if (file.getName().equalsIgnoreCase("word"))
{
boolean containsMedia = false;
File[] filesInWordFolder = file.listFiles();
for ( File file2 : filesInWordFolder )
{
if ( file2.getName().contains("media"))
{
containsMedia = true;
break;
}
}
if (containsMedia == false)
{
try
{
delete(file.getParentFile());
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
else if (file.isDirectory())
{
traverseDelete(file);
}
}
}
Sorry for the lack of commenting, but it's pretty self-explanatory, I think. Essentially what the code is supposed to do is traverses a set of files in a given directory, if it encounters a directory named "word", then it should list out the contents of word, and then if a directory called "media" does NOT exist, recursively delete everything within the parent directory of "word" down.
My main concern comes from this conditional:
if(!filesInWordFolder.toString().contains("media"))
Is that the correct way to say if the files in that array does not contain an instance of "image", go ahead and delete?

That won't work.
File[] filesInWordFolder = file.listFiles();
if(!filesInWordFolder.toString().contains("media"))
will give you a string representation of a File array -- which will typically have a reference.
You have to iterate through the files to find out if there's any in there that contain the word media.
boolean containsMedia = false;
for ( File file : filesInWordFolder ) {
if ( file.getName().contains("media") ){
containsMedia = true;
break;
}
// now check your boolean
if ( !containsMedia ) {

Well using toString() will give you a String representation of the file (in this case the files). The String representation should contain the file name. If your set purpose is to check for any instance of a file containing the word "media" in the directory, you are fine.
In the example you are printing the String representation of the File array. Instead you should iterate through the File array and check the String representation of each individual File as so:
for (int i = 0; i < file_array.length; i++) {
if ((File)file_array[i]).toString().equals("your_search_term")) {
// The file contains your search term
} else {
// Doesn't contain the search term.
}
}

Related

Compare files list to object List to delete files

I have a list of plans, each plan has a PDF in ("/web/managed/")
I wasn't deleting the files when I delete the plan, so now I'm trying to add a function to delete all files that are not have the ids in my plan list.
Files name always has the id.
Example: 6365_Test-LVLD.pdf
list of the object:
#Transaction
public List<StorePlan> getPlans() {
List<StorePlan> list = getCurrentSession().createCriteria(StorePlan.class).list();
return list;
}
then I'll get all the files from my folder:
protected File[] getPDFs() {
return new File("/web/managed/").listFiles();
}
here's my purge function:
protected void getPlanIds() {
int count = 0;
for(StorePlan plan : storePlanDao.getPlans()) {
for (File file : getPDFs()) {
String planFileId = file.getName().substring(0, 4);
if(plan.getId() != Integer.valueOf(planFileId)) {
file.delete();
count++;
}
}
}
}
with my code: it will delete everything from my folder. when I want to keep the files that will still have ids in the other list.
If I understood your question then this should work:
List<Integer> planIds = Lists.newArrayList();
for(StorePlan plan : storePlanDao.getPlans()){
planIds.add(plan.getId());
}
for (File file : getPDFs()) {
Integer planFileId = Integer.valueOf(file.getName().substring(0, 4))
if(!ids.contains(planFileId)) {
file.delete();
count++;
}
}
I think I see the problem. Instead of deleting the problem within the second loop have it set a Boolean to true and break out of the loop. Outside of the second loop have an if statement that, if true, deletes the file. So:
protected void getPlanIds() {
int count = 0;
for(StorePlan plan : storePlanDao.getPlans()) {
Boolean found = false;
for (File file : getPDFs()) {
String planFileId = file.getName().substring(0, 4);
if(plan.getId() == Integer.valueOf(planFileId)) {
found = true;
break;
} else {
count++;
}
}
if (!found) {
file.delete();
}
}
}
I apologize for bad formatting. I'm on mobile and passing time at work. xD

Recursing through a directory in java, I want to skip a step on the top level

I am trying to output a list of files within a directory recursively (not including the name of the name of the directory that I am starting with (just the contents of it and all files recursing down the tree after that)
here is what I have at the minute. It Might have errors here and there, but the idea is that it will print all the names of every file in the tree recursively. My problem is that I don't want it to print the name of the directory in which they live.
I think my problem is that I am using System.out.println at the start of the recursive method, which means it gets used every time. Which is desirable behavior for every directory BELOW the first one. Its an annoying little problem that I could use some help on. Thanks in advance.
public static void listFiles(String path)
{
File basedir = new File(path);
System.out.println(path.getName());
try
{
File[] files = basedir.listFiles();
for (File file : files)
{
// If Dealing with a directory, call recursively to the function
if (file.isDirectory())
{
listFiles(file.getPath());
}
else
{
System.out.println(file.getName());
}
}
}
catch(IOException ex)
{
System.out.println(ex);
}
}
public static void listFiles(String path, boolean firstCall)
{
File basedir = new File(path);
if(!firstCall)
{
System.out.println(path.getName());
}
try
{
File[] files = basedir.listFiles();
for (File file : files)
{
// If Dealing with a directory, call recursively to the function
if (file.isDirectory())
{
listFiles(file.getPath(), false); //false here because it is not the first call
}
else
{
System.out.println(file.getName());
}
}
}
catch(IOException ex)
{
System.out.println(ex);
}
}
Add a boolean parameter that specifies if it is the first call. When you call the method pass true to the parameter. Also path.getName() is not valid String doesn't have a function getName() maybe you meant basedir.getName()...also remove try catch block IOException can't occur there.

Finding a file in a directory and returning its full path and filename

This should be easy. This question (Java - Search for files in a directory) seemed to take me 99% of the way to where I needed to be, but that missing 1% is being a real SOB.
I need to find a specific file in a directory and return the full path and filename as a string. If there's more than one matching file, that's fine, I just need the first match.
The code below works inasmuch as it will recursively traverse a directory structure and return all matches -- I can see it happening when I put sysouts into the various parts of the method -- but I can't for the life of me make it stop when it finds a match and return me the value of the match.
I've tried substituting the FOR statement with a WHILE statement controlled by the the value of the foundfile variable as well as half a dozen other approaches but they all come down to the same end; when I find the matching file and set it to the foundfile variable in the "else if" clause, the for loop just keeps on iterating and overwrites the value of the foundfile variable with the "" value on the next loop. I would have thought that calling the setOutput method from within the "if else" clause would have set the value successfully until the list array was empty, but evidently not.
Clearly there is something about recursion and the persistence of parameters that I'm fundamentally misunderstanding. Can anyone illuminate?
package app;
import java.io.*;
import java.util.*;
class FindFile {
public String setOutput(String name, File file, String fileloc) {
String foundfile = fileloc;
File[] list = file.listFiles();
if (list != null)
for (File fil : list) {
if (fil.isDirectory()) {
setOutput(name, fil, foundfile);
} else if (fil.getName().contains(name)) {
foundfile = (fil.getParentFile() + "\\" + fil.getName());
setOutput(name, fil, foundfile);
}
}
return foundfile;
}
public static void main(String[] args) {
FindFile ff = new FindFile();
String thisstring = ff.setOutput(".jar", new File("/Temp/df384b41-198d-4fee-8704-70952d28cbde"), "");
System.out.println("output: " + thisstring);
}
}
You can return the file path when you find it. No need to check the other files if you are only interested in the first match:
Here is an example (not tested):
public String setOutput(String name, File file) {
File[] list = file.listFiles();
if (list != null) {
for (File fil : list) {
String path = null;
if (fil.isDirectory()) {
path = setOutput(name, fil);
if (path != null) {
return path;
}
} else if (fil.getName().contains(name)) {
path =fil.getAbsolutePath();
if (path != null) {
return path;
}
}
}
}
return null; // nothing found
}

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."

Check if directory can be opened and list its files

I'm developing a shell in Java. This shell can execute the command find 'regex'. This command finds all the files which have a name that matches the regex, recursively. The method that finds the files is:
public void findFile(String regExp, String dirName) {
File dir = new File(dirName);
if (dir.canRead() == false)
return;
File[] files = dir.listFiles();
for (File file : files) {
if (file.isFile() == true)
if (file.getName().matches(regExp) == true)
System.out.println(file.getAbsolutePath());
if (file.isDirectory() == true && file.canRead() == true) {
findFile(regExp, file.getAbsolutePath());
}
}
}
But this command fails if directory cannot be opened. For example, in D: partition, I have a hidden directory named found.00 (this directory might belong to the system) and I cannot open this directory. When the method encounters this directory, it fails. How can I check if directory belongs to the system and cannot be opened?
As you use file.canRead() already I would say you could surround the complete content of method findFile(String regExp, String dirName) with a try-catch. You can then catch and log or also ignore the access error. Try the following one please.
public void findFile(final String regExp, final String dirName) {
try {
final File dir = new File(dirName);
if (dir.canRead() == false) {
return;
}
final File[] files = dir.listFiles();
for (final File file : files) {
if (file.isFile() && file.getName().matches(regExp)) {
System.out.println(file.getAbsolutePath());
}
if ((file.isDirectory()) && (file.canRead())) {
findFile(regExp, file.getAbsolutePath());
}
}
} catch (final IOException ignore) {
System.out.println("No access to '"+dirName+"'.");
}
}

Categories

Resources