วิธีลบโฟลเดอร์ที่มีไฟล์โดยใช้ Java


105

ฉันต้องการสร้างและลบไดเร็กทอรีโดยใช้ Java แต่ใช้งานไม่ได้

File index = new File("/home/Work/Indexer1");
if (!index.exists()) {
    index.mkdir();
} else {
    index.delete();
    if (!index.exists()) {
        index.mkdir();
    }
}

3
เกิดอะไรขึ้นเมื่อคุณพยายาม?
Abimaran Kugathasan

คำถามคืออะไร?
Aniket Thakur

1
ไม่ได้ลบไฟล์ดัชนี
Mr.G


1
น่าเสียดายที่ @AniketThakur แนวทางดังกล่าวจะเป็นไปตามลิงก์สัญลักษณ์และลบไฟล์และไดเรกทอรีที่อาจไม่ได้ตั้งใจ
Hank Schultz

คำตอบ:


99

Java ไม่สามารถลบโฟลเดอร์ที่มีข้อมูลอยู่ คุณต้องลบไฟล์ทั้งหมดก่อนที่จะลบโฟลเดอร์

ใช้สิ่งที่ชอบ:

String[]entries = index.list();
for(String s: entries){
    File currentFile = new File(index.getPath(),s);
    currentFile.delete();
}

จากนั้นคุณจะสามารถลบโฟลเดอร์โดยใช้index.delete() Untested!


37
การดำเนินการนี้จะไม่ลบไดเรกทอรีย่อยที่ไม่ว่างเปล่า
ระบบ

13
คุณต้องเขียนวิธีการเรียกซ้ำหรือใช้FileUtils.deleteDirectoryตามที่ @Francesco Menzani กล่าว
EN20

4
ระวังให้มาก หากดัชนีเป็นลิงก์สัญลักษณ์ไปยังไดเรกทอรีอื่นคุณจะต้องลบเนื้อหาของไดเรกทอรีอื่น น่าเสียดายที่ฉันยังไม่พบวิธีที่ดีในการตรวจจับลิงก์สัญลักษณ์บน Windows ใน Java 6 แม้ว่า Java 7 จะให้ Files.isSymbolicLink ()
Hank Schultz

1
วิธีแก้ไข: ห่อโค้ดส่วนif (!index.delete()) {...}นี้เข้า จากนั้นหากดัชนีเป็นลิงก์สัญลักษณ์ดัชนีจะถูกลบโดยไม่คำนึงว่าจะมีเนื้อหาหรือไม่
Hank Schultz

สิ่งนี้จะส่ง NullPointerException หากมีข้อยกเว้น I / O ขณะอ่านไดเร็กทอรี รหัสควรตรวจสอบว่าentriesเป็นโมฆะหรือไม่
ถึง

179

เพียงซับเดียว

import org.apache.commons.io.FileUtils;

FileUtils.deleteDirectory(new File(destination));

เอกสารที่นี่



13
อืมไม่. นี่คือซับเดียวที่มีการพึ่งพาภายนอกซึ่งเป็นสิ่งสำคัญที่ต้องจำไว้ ครั้งเดียวที่ใช้การพึ่งพาภายนอกเช่นนี้เป็นเรื่องง่ายเมื่อคุณทำโครงการบ้านส่วนตัวหรือ บริษัท ของคุณไม่สนใจเกี่ยวกับความเป็นไปได้ที่จะถูกฟ้องร้อง
Searchengine27

11
@ searchengine27 แต่ดูเหมือนว่าห้องสมุดที่อยู่ภายใต้ Apache Commons ดังนั้นความเสี่ยงของการฟ้องเป็นเล็กน้อยwhitesourcesoftware.com/whitesource-blog/...
simtim

1
@simtim คุณพลาดประเด็นทั้งหมด บริษัท จะไม่อนุมัติให้ใช้ห้องสมุดโดยไม่มีทีมทนายความคอยดูแลเงื่อนไขการใช้งานและข้อตกลงของผู้ใช้และเอกสารทางกฎหมายอื่น ๆ ที่เกี่ยวข้องกับห้องสมุดก่อน บางคนต้องจ่ายค่าทนายความเหล่านั้น ... บางครั้งก็ไม่มีใครต้องการซึ่งหมายความว่าผู้พัฒนาไม่ได้ใช้งาน ยิ่งคุณทำงานให้กับ บริษัท ใหญ่เท่าไหร่คุณก็ต้องผ่านเทปสีแดงมากขึ้นเท่านั้น
Searchengine27

19
@ Searchengine27 ไม่คุณพลาดประเด็นทั้งหมด บริษัท ที่ต้องการกองทัพทนายความเพื่ออนุญาตให้ใช้ apache commons เป็นพยาธิวิทยาที่สมบูรณ์และไม่มีอะไรใกล้เคียงกับบรรทัดฐานในโลกไอที ฉันไม่เคยได้ยินว่าใครมีปัญหาเช่นนี้และหากคุณมีปัญหาดังกล่าวคุณมักจะเข้าถึง SO ที่ถูกบล็อกดังนั้นคำตอบจะไม่สามารถเข้าถึงได้สำหรับคุณ
9ilsdx 9rvj 0lo

94

งานนี้และในขณะที่มันดูไม่มีประสิทธิภาพในการข้ามการทดสอบไดเรกทอรีก็ไม่ได้: listFiles()การทดสอบที่เกิดขึ้นในทันที

void deleteDir(File file) {
    File[] contents = file.listFiles();
    if (contents != null) {
        for (File f : contents) {
            deleteDir(f);
        }
    }
    file.delete();
}

อัปเดตเพื่อหลีกเลี่ยงการติดตามลิงก์สัญลักษณ์:

void deleteDir(File file) {
    File[] contents = file.listFiles();
    if (contents != null) {
        for (File f : contents) {
            if (! Files.isSymbolicLink(f.toPath())) {
                deleteDir(f);
            }
        }
    }
    file.delete();
}

2
ปรากฎว่ามีข้อบกพร่องในสิ่งนี้ หากกระบวนการอื่นลบไฟล์ระหว่างการวนซ้ำอาจทำให้เกิดข้อยกเว้นที่ควรถูกจับและละเว้น
Jeff Learman

2
@ 9ilsdx9rvj0lo แทนที่จะเป็นคนขี้ขลาดบางทีคุณอาจให้การแก้ไขเพื่อจัดการ symlinks OP ไม่ได้พูดอะไรเกี่ยวกับลิงก์สัญลักษณ์ในโพสต์ของเขา เพียงแค่สร้างและลบไดเร็กทอรี โปรดระบุรายการ "หลายสิ่งที่ขาดหายไป" ช่วยเราด้วย
Perry Tew

@PerryTew ฉันไม่ได้ขี้เก๊ก ฉันแค่ชี้ให้เห็นว่าฉันไม่เห็นด้วยอย่างยิ่งกับความคิดเห็นของคุณเกี่ยวกับคำตอบที่ดีกว่าเนื่องจากไม่มีการใช้ไลบรารีภายนอก มันไม่ใช่. มีเหตุผลที่ดีที่ผู้คนใช้ apache commons: คุณไม่จำเป็นต้องตั้งโปรแกรมอะไรด้วยตัวเอง Symlinks เป็นเพียงตัวอย่างของสิ่งที่คุณจะพลาดการเขียนทุกอย่างตั้งแต่เริ่มต้น
9ilsdx 9rvj 0lo

2
ไม่ใช่เรื่องดีขึ้น / แย่ลง แต่ข้อดีข้อเสีย การไม่พึ่งพาห้องสมุดภายนอกบางครั้งก็เป็นประโยชน์อย่างมาก แน่นอนว่าการใช้ซอฟต์แวร์ที่พยายามและจริงมีประโยชน์อย่างมาก ขึ้นอยู่กับนักพัฒนาที่จะปรับสมดุลของปัญหา หากมีข้อบกพร่องนอกเหนือจากสองข้อที่กล่าวไปแล้วเราต้องการทราบข้อมูลเหล่านี้อย่างแน่นอน
Jeff Learman

32

ฉันชอบวิธีนี้บน java 8:

  Files.walk(pathToBeDeleted)
    .sorted(Comparator.reverseOrder())
    .map(Path::toFile)
    .forEach(File::delete);

จากเว็บไซต์นี้: http://www.baeldung.com/java-delete-directory


2
โปรดทราบว่าสิ่งนี้อาจมีปัญหาเรื่องความสามารถในการปรับขนาดเนื่องจากสร้างรายการทั้งหมดสร้างสำเนาที่เรียงลำดับแล้ววนซ้ำบนสำเนาที่เรียงลำดับ ย้อนกลับไปในวันเก่าที่เลวร้ายเมื่อความทรงจำไม่รู้จักเหนื่อยนี่คงเป็นความคิดที่แย่มาก มันกระชับ แต่มีต้นทุนในพื้นที่ (O (N) เทียบกับ O (1)) และประสิทธิภาพ (O (N log N) เทียบกับ O (N)) สิ่งนี้จะไม่สำคัญในกรณีการใช้งานส่วนใหญ่
Jeff Learman

ฉันควรจะพูดว่า "space O (N) vs O (ความลึก)" ด้านบนโดยที่ความลึกคือความลึกของ
แผนผัง

1
สิ่งนี้สวยงามใช้งานได้และไม่ต้องพึ่งพาไลบรารีภายนอก ชอบมาก
ลีโอ

นี่ไม่มีปัญหาเรื่อง file handle รั่วหรือเปล่า? ตัวอย่างนี้ไม่ได้ปิดสตรีมที่ส่งคืนFiles.walk()ซึ่งระบุไว้อย่างชัดเจนในเอกสาร API ฉันรู้ว่าถ้าคุณไม่ปิดสตรีมที่ส่งคืนFiles.list()ตัวอย่างเช่นคุณสามารถจัดการได้หมดและโปรแกรมจะหยุดทำงาน ดูเช่นstackoverflow.com/q/36990053/421049และstackoverflow.com/q/26997240/421049
Garret Wilson

24

ใน JDK 7 คุณสามารถใช้Files.walkFileTree()และFiles.deleteIfExists()เพื่อลบโครงสร้างไฟล์ (ตัวอย่าง: http://fahdshariff.blogspot.ru/2011/08/java-7-deleting-directory-by-walking.html )

ใน JDK 6 วิธีหนึ่งที่เป็นไปได้คือใช้FileUtils.deleteQuietlyจาก Apache Commons ซึ่งจะลบไฟล์ไดเร็กทอรีหรือไดเร็กทอรีที่มีไฟล์และไดเร็กทอรีย่อย


6
นี่คือตัวอย่าง: fahdshariff.blogspot.ru/2011/08/…
Andrey Chaschev

23

การใช้ Apache Commons-IO เป็นไปตามซับเดียว:

import org.apache.commons.io.FileUtils;

FileUtils.forceDelete(new File(destination));

นี่คือ performant (เล็กน้อย) FileUtils.deleteDirectoryมากกว่า


group: 'commons-io', name: 'commons-io', version: '2. +' - มีประโยชน์
ไมค์หนู

10

ดังที่กล่าวไว้ Java ไม่สามารถลบโฟลเดอร์ที่มีไฟล์ได้ดังนั้นก่อนอื่นให้ลบไฟล์จากนั้นจึงเลือกโฟลเดอร์นั้น

นี่คือตัวอย่างง่ายๆในการดำเนินการนี้:

import org.apache.commons.io.FileUtils;



// First, remove files from into the folder 
FileUtils.cleanDirectory(folder/path);

// Then, remove the folder
FileUtils.deleteDirectory(folder/path);

หรือ:

FileUtils.forceDelete(new File(destination));

9

เวอร์ชันเรียกซ้ำพื้นฐานของฉันที่ทำงานกับ JDK เวอร์ชันเก่ากว่า:

public static void deleteFile(File element) {
    if (element.isDirectory()) {
        for (File sub : element.listFiles()) {
            deleteFile(sub);
        }
    }
    element.delete();
}

2
สิ่งนี้จะส่ง NullPointerException หากมีข้อยกเว้น I / O ขณะอ่านไดเร็กทอรี รหัสควรตรวจสอบว่าผลตอบแทนที่เป็นโมฆะมากกว่าโทรlistFiles() isDirectory()
mernst

9

นี่เป็นทางออกที่ดีที่สุดสำหรับJava 7+:

public static void deleteDirectory(String directoryFilePath) throws IOException
{
    Path directory = Paths.get(directoryFilePath);

    if (Files.exists(directory))
    {
        Files.walkFileTree(directory, new SimpleFileVisitor<Path>()
        {
            @Override
            public FileVisitResult visitFile(Path path, BasicFileAttributes basicFileAttributes) throws IOException
            {
                Files.delete(path);
                return FileVisitResult.CONTINUE;
            }

            @Override
            public FileVisitResult postVisitDirectory(Path directory, IOException ioException) throws IOException
            {
                Files.delete(directory);
                return FileVisitResult.CONTINUE;
            }
        });
    }
}

6

ฝรั่ง 21+ ไปช่วย. ใช้เฉพาะในกรณีที่ไม่มีลิงก์สัญลักษณ์ที่ชี้ออกจากไดเร็กทอรีที่จะลบ

com.google.common.io.MoreFiles.deleteRecursively(
      file.toPath(),
      RecursiveDeleteOption.ALLOW_INSECURE
) ;

(คำถามนี้ได้รับการจัดทำดัชนีอย่างดีโดย Google ดังนั้นคนอื่น ๆ usig Guava อาจยินดีที่จะพบคำตอบนี้แม้ว่าจะซ้ำซ้อนกับคำตอบอื่น ๆ ก็ตาม)


4

ฉันชอบการแก้ปัญหานี้มากที่สุด ไม่ใช้ไลบรารีของบุคคลที่สาม แต่จะใช้NIO2ของ Java 7 แทน

/**
 * Deletes Folder with all of its content
 *
 * @param folder path to folder which should be deleted
 */
public static void deleteFolderAndItsContent(final Path folder) throws IOException {
    Files.walkFileTree(folder, new SimpleFileVisitor<Path>() {
        @Override
        public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
            Files.delete(file);
            return FileVisitResult.CONTINUE;
        }

        @Override
        public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
            if (exc != null) {
                throw exc;
            }
            Files.delete(dir);
            return FileVisitResult.CONTINUE;
        }
    });
}

3

อีกทางเลือกหนึ่งคือใช้org.springframework.util.FileSystemUtilsวิธีการที่เกี่ยวข้องของ Spring ซึ่งจะลบเนื้อหาทั้งหมดของไดเรกทอรีซ้ำ ๆ

File directoryToDelete = new File(<your_directory_path_to_delete>);
FileSystemUtils.deleteRecursively(directoryToDelete);

ที่จะทำงาน!


2

ในเรื่องนี้

index.delete();

            if (!index.exists())
               {
                   index.mkdir();
               }

คุณกำลังโทร

 if (!index.exists())
                   {
                       index.mkdir();
                   }

หลังจาก

index.delete();

ซึ่งหมายความว่าคุณกำลังสร้างไฟล์อีกครั้งหลังจากลบ File.delete ()ส่งคืนค่าบูลีนดังนั้นหากคุณต้องการตรวจสอบให้ทำSystem.out.println(index.delete());หากคุณได้รับtrueนั่นหมายความว่าไฟล์นั้นถูกลบ

File index = new File("/home/Work/Indexer1");
    if (!index.exists())
       {
             index.mkdir();
       }
    else{
            System.out.println(index.delete());//If you get true then file is deleted




            if (!index.exists())
               {
                   index.mkdir();// here you are creating again after deleting the file
               }




        }

จากความคิดเห็นที่ระบุด้านล่างคำตอบที่อัปเดตเป็นเช่นนี้

File f=new File("full_path");//full path like c:/home/ri
    if(f.exists())
    {
        f.delete();
    }
    else
    {
        try {
            //f.createNewFile();//this will create a file
            f.mkdir();//this create a folder
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

2

หากคุณมีโฟลเดอร์ย่อยคุณจะพบปัญหากับคำตอบของ Cemron ดังนั้นคุณควรสร้างวิธีการที่ใช้งานได้ดังนี้:

private void deleteTempFile(File tempFile) {
        try
        {
            if(tempFile.isDirectory()){
               File[] entries = tempFile.listFiles();
               for(File currentFile: entries){
                   deleteTempFile(currentFile);
               }
               tempFile.delete();
            }else{
               tempFile.delete();
            }
        getLogger().info("DELETED Temporal File: " + tempFile.getPath());
        }
        catch(Throwable t)
        {
            getLogger().error("Could not DELETE file: " + tempFile.getPath(), t);
        }
    }


1

directry ไม่สามารถลบได้หากมีไฟล์อยู่ดังนั้นคุณอาจต้องลบไฟล์ที่อยู่ภายในก่อนจากนั้นจึงไดเร็กทอรี

public class DeleteFileFolder {

public DeleteFileFolder(String path) {

    File file = new File(path);
    if(file.exists())
    {
        do{
            delete(file);
        }while(file.exists());
    }else
    {
        System.out.println("File or Folder not found : "+path);
    }

}
private void delete(File file)
{
    if(file.isDirectory())
    {
        String fileList[] = file.list();
        if(fileList.length == 0)
        {
            System.out.println("Deleting Directory : "+file.getPath());
            file.delete();
        }else
        {
            int size = fileList.length;
            for(int i = 0 ; i < size ; i++)
            {
                String fileName = fileList[i];
                System.out.println("File path : "+file.getPath()+" and name :"+fileName);
                String fullPath = file.getPath()+"/"+fileName;
                File fileOrFolder = new File(fullPath);
                System.out.println("Full Path :"+fileOrFolder.getPath());
                delete(fileOrFolder);
            }
        }
    }else
    {
        System.out.println("Deleting file : "+file.getPath());
        file.delete();
    }
}

1

คุณสามารถโทรซ้ำได้หากมีไดเรกทอรีย่อยอยู่

import java.io.File;

class DeleteDir {
public static void main(String args[]) {
deleteDirectory(new File(args[0]));
}

static public boolean deleteDirectory(File path) {
if( path.exists() ) {
  File[] files = path.listFiles();
  for(int i=0; i<files.length; i++) {
     if(files[i].isDirectory()) {
       deleteDirectory(files[i]);
     }
     else {
       files[i].delete();
     }
  }
}
return( path.delete() );
}
}


1

คำตอบส่วนใหญ่ (แม้กระทั่งล่าสุด) ที่อ้างถึงคลาส JDK ขึ้นอยู่กับFile.delete()แต่นั่นเป็น API ที่มีข้อบกพร่องเนื่องจากการดำเนินการอาจล้มเหลวโดยไม่โต้ตอบ เอกสารวิธีฯ :
java.io.File.delete()

โปรดสังเกตว่าjava.nio.file.FilesคลาสกำหนดdeleteวิธีการโยนIOExceptionเมื่อไฟล์ไม่สามารถลบได้ สิ่งนี้มีประโยชน์สำหรับการรายงานข้อผิดพลาดและเพื่อวินิจฉัยสาเหตุที่ไม่สามารถลบไฟล์ได้

แทนคุณควรสนับสนุนFiles.delete(Path p) ที่พ่นIOExceptionด้วยข้อความแสดงข้อผิดพลาด

รหัสจริงสามารถเขียนได้เช่น:

Path index = Paths.get("/home/Work/Indexer1");

if (!Files.exists(index)) {
    index = Files.createDirectories(index);
} else {

    Files.walk(index)
         .sorted(Comparator.reverseOrder())  // as the file tree is traversed depth-first and that deleted dirs have to be empty  
         .forEach(t -> {
             try {
                 Files.delete(t);
             } catch (IOException e) {
                 // LOG the exception and potentially stop the processing

             }
         });
    if (!Files.exists(index)) {
        index = Files.createDirectories(index);
    }
}


0
private void deleteFileOrFolder(File file){
    try {
        for (File f : file.listFiles()) {
            f.delete();
            deleteFileOrFolder(f);
        }
    } catch (Exception e) {
        e.printStackTrace(System.err);
    }
}

0
        import org.apache.commons.io.FileUtils;

        List<String> directory =  new ArrayList(); 
        directory.add("test-output"); 
        directory.add("Reports/executions"); 
        directory.add("Reports/index.html"); 
        directory.add("Reports/report.properties"); 
        for(int count = 0 ; count < directory.size() ; count ++)
        {
        String destination = directory.get(count);
        deleteDirectory(destination);
        }





      public void deleteDirectory(String path) {

        File file  = new File(path);
        if(file.isDirectory()){
             System.out.println("Deleting Directory :" + path);
            try {
                FileUtils.deleteDirectory(new File(path)); //deletes the whole folder
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        else {
        System.out.println("Deleting File :" + path);
            //it is a simple file. Proceed for deletion
            file.delete();
        }

    }

ทำงานเหมือน Charm สำหรับทั้งโฟลเดอร์และไฟล์ สลาม :)


-1

ลบออกจากส่วนอื่น

File index = new File("/home/Work/Indexer1");
if (!index.exists())
{
     index.mkdir();
     System.out.println("Dir Not present. Creating new one!");
}
index.delete();
System.out.println("File deleted successfully");

-1

คำตอบเหล่านี้บางส่วนดูเหมือนจะยาวโดยไม่จำเป็น:

if (directory.exists()) {
    for (File file : directory.listFiles()) {
        file.delete();
    }
    directory.delete();
}

ใช้ได้กับไดเรกทอรีย่อยด้วย


-3

คุณสามารถใช้ฟังก์ชันนี้

public void delete()    
{   
    File f = new File("E://implementation1/");
    File[] files = f.listFiles();
    for (File file : files) {
        file.delete();
    }
}

ทำงานได้ดีกับไดเรกทอรีที่มีไฟล์ปิดทั้งหมด แต่เมื่อลองกับไดเร็กทอรีที่มีไฟล์ที่เปิดอยู่มันไม่ได้ผล คุณช่วยฉันหาวิธีลบโฟลเดอร์
แรงบันดาลใจ

2
การดำเนินการนี้จะไม่ลบไดเรกทอรีย่อยที่ไม่ว่างเปล่า
ปาง
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.