Cara menghapus folder dengan file menggunakan Java

104

Saya ingin membuat dan menghapus direktori menggunakan Java, tetapi tidak berhasil.

File index = new File("/home/Work/Indexer1");
if (!index.exists()) {
    index.mkdir();
} else {
    index.delete();
    if (!index.exists()) {
        index.mkdir();
    }
}
Tuan G.
sumber
3
Apa yang terjadi saat Anda mencobanya?
Abimaran Kugathasan
Apa pertanyaannya?
Aniket Thakur
1
file indeks tidak dihapus.
Tn. G
1
Lihat Cara menghapus direktori di Java
Aniket Thakur
1
Sayangnya, @AniketThakur, pendekatan itu akan mengikuti tautan simbolis dan menghapus file dan direktori yang mungkin tidak dimaksudkan.
Hank Schultz

Jawaban:

99

Java tidak dapat menghapus folder dengan data di dalamnya. Anda harus menghapus semua file sebelum menghapus folder.

Gunakan sesuatu seperti:

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

Maka Anda seharusnya dapat menghapus folder tersebut dengan menggunakan index.delete() Untested!

Cemron
sumber
37
Ini tidak akan menghapus subdirektori yang tidak kosong.
Francesco Menzani
13
Anda harus menulis metode rekursif atau gunakan FileUtils.deleteDirectoryseperti yang dikatakan @Francesco Menzani.
EN20
4
Berhati-hatilah. Jika indeks adalah tautan simbolis ke direktori lain, Anda akhirnya akan menghapus konten direktori lain. Sayangnya, saya belum menemukan cara yang baik untuk mendeteksi tautan simbolik pada Windows di Java 6, meskipun Java 7 menyediakan Files.isSymbolicLink ().
Hank Schultz
1
Solusi: bungkus bagian kode ini if (!index.delete()) {...}. Kemudian, jika indeks adalah tautan simbolis, itu dihapus terlepas dari apakah indeks itu memiliki isinya.
Hank Schultz
Ini akan memunculkan NullPointerException jika ada pengecualian I / O saat membaca direktori. Kode harus memeriksa apakah entriesnol.
selesai
178

Hanya satu baris.

import org.apache.commons.io.FileUtils;

FileUtils.deleteDirectory(new File(destination));

Dokumentasi di sini

Barry Knapp
sumber
13
um ... tidak. Ini adalah satu baris dengan ketergantungan eksternal, yang merupakan hal penting untuk diingat. Satu-satunya saat menggunakan ketergantungan eksternal seperti ini sesederhana ini adalah ketika Anda melakukan proyek rumah pribadi, atau perusahaan Anda benar-benar tidak peduli tentang kemungkinan dituntut.
searchengine27
11
@ searchengine27 tetapi tampaknya perpustakaan tersebut berada di bawah Apache Commons sehingga risiko dituntut dapat diabaikan whitesourcesoftware.com/whitesource-blog/… .
simtim
1
@imtim Anda kehilangan intinya sepenuhnya. Perusahaan tidak akan pernah menyetujui perpustakaan untuk digunakan tanpa tim pengacara yang membahas persyaratan penggunaan dan perjanjian pengguna akhir, dan dokumen hukum lainnya yang terkait dengan perpustakaan terlebih dahulu. Seseorang harus membayar pengacara itu ... terkadang tidak ada yang mau, yang berarti pengembang tidak dapat menggunakannya. Semakin besar perusahaan tempat Anda bekerja, semakin banyak birokrasi yang harus Anda lalui.
searchengine27
19
@ searchengine27 tidak, Anda kehilangan intinya sepenuhnya. Perusahaan yang membutuhkan sekumpulan pengacara untuk mengizinkan penggunaan apache commons adalah patologi absolut, dan tidak ada yang mendekati norma di dunia TI. Saya belum pernah mendengar ada orang yang mengalami masalah seperti itu dan jika Anda memiliki masalah seperti itu, kemungkinan besar akses ke SO diblokir sehingga jawabannya tidak akan dapat diakses oleh Anda.
9ilsdx 9rvj 0lo
94

Ini berfungsi, dan meskipun tampaknya tidak efisien untuk melewati pengujian direktori, sebenarnya tidak: pengujian langsung dilakukan di listFiles().

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

Perbarui, untuk menghindari tautan simbolis berikut:

void deleteDir(File file) {
    File[] contents = file.listFiles();
    if (contents != null) {
        for (File f : contents) {
            if (! Files.isSymbolicLink(f.toPath())) {
                deleteDir(f);
            }
        }
    }
    file.delete();
}
Jeff Learman
sumber
2
Ternyata, ada bug dalam hal ini. Jika proses lain menghapus file selama perulangan, ini dapat menyebabkan pengecualian yang harus ditangkap dan diabaikan.
Jeff Learman
2
@ 9ilsdx9rvj0lo Daripada bersikap snarky, mungkin Anda bisa memberikan edit untuk menangani symlink. OP tidak mengatakan apa - apa tentang tautan simbolis di posnya. Hanya membuat dan menghapus direktori. Harap juga mencantumkan "banyak hal yang hilang". Bantu kami.
Perry Tew
@PerryTew Aku tidak sombong. Saya hanya menunjukkan, bahwa saya sangat tidak setuju dengan komentar Anda tentang jawaban yang lebih baik karena tidak ada perpustakaan eksternal yang digunakan. Bukan itu. Ada alasan bagus mengapa orang menggunakan apache commons: Anda tidak perlu memprogram sendiri apa pun. Symlinks hanyalah contoh hal-hal yang akan Anda lewatkan untuk menulis semuanya dari awal.
9ilsdx 9rvj 0lo
2
Ini bukan masalah lebih baik / lebih buruk, tapi pro dan kontra. Terkadang tidak bergantung pada perpustakaan eksternal merupakan manfaat yang signifikan. Tentu saja, ada keuntungan signifikan menggunakan perangkat lunak yang sudah terbukti dan benar. Terserah pengembang untuk menyeimbangkan masalah. Jika ada bug selain dua yang telah disebutkan, kami pasti ingin mengetahuinya.
Jeff Learman
31

Saya lebih suka solusi ini di java 8:

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

Dari situs ini: http://www.baeldung.com/java-delete-directory

nirmal
sumber
2
Perhatikan bahwa ini mungkin memiliki masalah skalabilitas karena ini membangun daftar lengkap, membuat salinan yang diurutkan, dan kemudian mengulangi salinan yang diurutkan. Kembali ke masa lalu yang buruk ketika ingatan tidak pernah habis, ini akan menjadi ide yang sangat buruk. Ini ringkas tetapi dengan biaya dalam ruang (O (N) vs O (1)) dan efisiensi (O (N log N) vs O (N)). Ini tidak masalah dalam kebanyakan kasus penggunaan.
Jeff Learman
Saya seharusnya mengatakan "spasi O (N) vs O (kedalaman)" di atas, di mana kedalaman adalah kedalaman pohon direktori (membandingkan solusi ini dengan solusi rekursif.)
Jeff Learman
1
ini elegan, berfungsi dan tidak bergantung pada perpustakaan eksternal. menyukainya
Leo
Bukankah ini masalah kebocoran file handle? Contoh ini tidak menutup aliran yang dikembalikan oleh Files.walk(), yang secara eksplisit ditunjukkan dalam dokumen API. Saya tahu bahwa jika Anda tidak menutup aliran yang dikembalikan oleh Files.list()misalnya, Anda dapat kehabisan pegangan dan program akan macet. Lihat misalnya stackoverflow.com/q/36990053/421049 dan stackoverflow.com/q/26997240/421049 .
Garret Wilson
23

Menggunakan Apache Commons-IO, ini mengikuti satu baris:

import org.apache.commons.io.FileUtils;

FileUtils.forceDelete(new File(destination));

Ini (sedikit) lebih berkinerja daripada FileUtils.deleteDirectory.

JRA_TLL
sumber
grup: 'commons-io', nama: 'commons-io', versi: '2. +' - berguna
mike rodent
10

Seperti yang disebutkan, Java tidak dapat menghapus folder yang berisi file, jadi hapus file terlebih dahulu lalu foldernya.

Berikut contoh sederhana untuk melakukan ini:

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);

Atau:

FileUtils.forceDelete(new File(destination));
Gavriel Cohen
sumber
9

Versi rekursif dasar saya, bekerja dengan versi JDK yang lebih lama:

public static void deleteFile(File element) {
    if (element.isDirectory()) {
        for (File sub : element.listFiles()) {
            deleteFile(sub);
        }
    }
    element.delete();
}
Pierre Lemée
sumber
2
Ini akan memunculkan NullPointerException jika ada pengecualian I / O saat membaca direktori. Kode harus memeriksa apakah listFiles()mengembalikan null, daripada memanggil isDirectory().
selesai
9

Ini adalah solusi terbaik untuk 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;
            }
        });
    }
}
BullyWiiPlaza
sumber
6

Jambu biji 21+ untuk menyelamatkan. Gunakan hanya jika tidak ada symlink yang mengarah keluar dari direktori yang akan dihapus.

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

(Pertanyaan ini diindeks dengan baik oleh Google, jadi orang lain yang menggunakan Jambu mungkin akan senang menemukan jawaban ini, meskipun jawaban itu mubazir dengan jawaban lain di tempat lain.)

Laurent Caillette
sumber
4

Saya paling suka solusi ini. Itu tidak menggunakan perpustakaan pihak ke-3, melainkan menggunakan NIO2 dari 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;
        }
    });
}
Javo
sumber
3

Satu pilihan lagi adalah menggunakan org.springframework.util.FileSystemUtilsmetode relevan Spring yang secara rekursif akan menghapus semua konten direktori.

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

Itu akan berhasil!

dZ.
sumber
2

Di dalam

index.delete();

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

Anda menelepon

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

setelah

index.delete();

Ini berarti Anda membuat file lagi setelah menghapus File.delete () mengembalikan nilai boolean. Jadi jika Anda ingin memeriksa maka lakukan System.out.println(index.delete());jika Anda mendapatkan truemaka ini berarti file tersebut dihapus

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
               }




        }

dari komentar yang diberikan di bawah ini, jawaban yang diperbarui seperti ini

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();
        }
    }
SpringLearner
sumber
2

Jika Anda memiliki subfolder, Anda akan menemukan masalah dengan jawaban Cemron. jadi Anda harus membuat metode yang berfungsi seperti ini:

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);
        }
    }
Panthro
sumber
2

Anda dapat menggunakan FileUtils.deleteDirectory . JAVA tidak dapat menghapus folder yang tidak kosong dengan File.delete () .

Issam Ressani
sumber
1

directry tidak bisa begitu saja menghapus jika memiliki file sehingga Anda mungkin perlu menghapus file di dalamnya terlebih dahulu dan kemudian direktori

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();
    }
}
Indranil.Bharambe
sumber
1

Anda dapat melakukan panggilan rekursif jika ada sub direktori

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() );
}
}
prem30488.dll
sumber
1

kita bisa menggunakan spring-coreketergantungan;

boolean result = FileSystemUtils.deleteRecursively(file);
Kanagavelu Sugumar
sumber
1

Sebagian besar jawaban (bahkan terbaru) yang merujuk pada kelas JDK bergantung File.delete()tetapi itu adalah API yang cacat karena operasi mungkin gagal secara diam-diam.
The java.io.File.delete()negara metode dokumentasi:

Perhatikan bahwa java.nio.file.Fileskelas mendefinisikan deletemetode untuk melempar IOExceptionketika file tidak dapat dihapus. Ini berguna untuk pelaporan kesalahan dan untuk mendiagnosis mengapa file tidak dapat dihapus.

Sebagai gantinya, Anda harus memilih Files.delete(Path p) yang melempar IOExceptiondengan pesan kesalahan.

Kode sebenarnya dapat ditulis seperti:

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);
    }
}
davidxxx
sumber
0

Anda dapat mencoba sebagai berikut

  File dir = new File("path");
   if (dir.isDirectory())
   {
         dir.delete();
   }

Jika ada sub folder di dalam folder Anda, Anda mungkin perlu menghapusnya secara rekursif.

Ruchira Gayan Ranaweera
sumber
0
private void deleteFileOrFolder(File file){
    try {
        for (File f : file.listFiles()) {
            f.delete();
            deleteFileOrFolder(f);
        }
    } catch (Exception e) {
        e.printStackTrace(System.err);
    }
}
Marcelo Lopes
sumber
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();
        }

    }

Bekerja seperti Mantra. Untuk folder dan file. Salam :)

Mushtaque Ahmed
sumber
-1

Hapus dari bagian lain

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");
Aniket Thakur
sumber
-1

Beberapa dari jawaban ini sepertinya terlalu panjang:

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

Bekerja untuk sub direktori juga.

Adam Short
sumber
-3

Anda dapat menggunakan fungsi ini

public void delete()    
{   
    File f = new File("E://implementation1/");
    File[] files = f.listFiles();
    for (File file : files) {
        file.delete();
    }
}
Piyush Rumao
sumber
Ini berfungsi dengan baik dengan direktori dengan semua file tertutup. Tetapi ketika dicoba pada direktori dengan file terbuka itu tidak berhasil. Dapatkah Anda membantu saya menemukan cara untuk menghapus folder meskipun ada file yang terbuka
Piyush Rumao
2
Ini tidak akan menghapus subdirektori yang tidak kosong.
Pang