Java kullanılarak dosya içeren bir klasör nasıl silinir


104

Java kullanarak bir dizin oluşturmak ve silmek istiyorum, ancak çalışmıyor.

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

3
Denediğinde ne oldu?
Abimaran Kugathasan

Soru nedir?
Aniket Thakur

1
dizin dosyası kaldırılmaz.
G


1
Ne yazık ki, @AniketThakur, bu yaklaşım sembolik bağlantıları izleyecek ve amaçlanmamış olabilecek dosya ve dizinleri silecektir.
Hank Schultz

Yanıtlar:


99

Java, içinde veri bulunan klasörleri silemez. Klasörü silmeden önce tüm dosyaları silmelisiniz.

Şunun gibi bir şey kullanın:

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

Ardından, index.delete() Test Edilmemiş'i kullanarak klasörü silebilirsiniz !


37
Bu, boş olmayan alt dizinleri silmez.
Francesco Menzani

13
FileUtils.deleteDirectory@Francesco Menzani'nin dediği gibi yinelemeli bir yöntem yazmalı veya kullanmalısınız .
EN20

4
Çok dikkatli ol. İndeks başka bir dizine sembolik bir bağlantı ise, diğer dizinin içeriğini silersiniz. Maalesef Java 6'da Windows'ta sembolik bağlantıları saptamanın iyi bir yolunu bulamadım, ancak Java 7, Files.isSymbolicLink () sağlıyor.
Hank Schultz

1
Çözüm: Bu kod parçasını içeri sarın if (!index.delete()) {...}. Ardından, dizin sembolik bir bağlantıysa, içeriğinde görünüp görünmediğine bakılmaksızın silinir.
Hank Schultz

Bu, dizini okurken bir G / Ç istisnası varsa bir NullPointerException oluşturur. Kod entriesboş olup olmadığını kontrol etmelidir .
mernst

178

Sadece tek satırlık.

import org.apache.commons.io.FileUtils;

FileUtils.deleteDirectory(new File(destination));

Belgeler burada



13
um ... hayır. Bu, akılda tutulması gereken önemli bir şey olan, dışa bağımlılığı olan tek satırlık bir programdır. Bunun gibi harici bir bağımlılığı kullanmanın tek zamanı, kişisel bir ev projesi yaptığınız veya şirketinizin dava edilme olasılığını gerçekten umursamadığı zamandır.
searchengine27

11
@ searchengine27, ancak kütüphane Apache Commons altında gibi görünüyor, bu nedenle dava edilme riski ihmal edilebilir whitesourcesoftware.com/whitesource-blog/… .
simtim

1
@simtim noktayı tamamen kaçırıyorsun. Bir şirket, bir avukat ekibi tarafından kullanım koşulları ve son kullanıcı sözleşmeleri ve önce kütüphaneyle ilgili diğer yasal belgeler hakkında bilgi vermeden kullanılmasını asla onaylamaz. Birinin bu avukatlara ödeme yapması gerekiyor ... bazen kimse ödemek istemiyor, bu da geliştiricinin kullanamayacağı anlamına geliyor. Çalıştığınız şirket ne kadar büyükse, o kadar fazla bürokrasi geçmeniz gerekir.
searchengine27

19
@ searchengine27 hayır, noktayı tamamen kaçırıyorsun. Apache commons'ı kullanmasına izin vermek için bir avukat ordusuna ihtiyaç duyan bir şirket mutlak patolojidir ve BT dünyasında normlara yakın bir şey değildir. Hiç kimsenin bu tür sorunları olduğunu duymadım ve bu tür sorunlarınız varsa, büyük olasılıkla SO'ya erişiminiz engelleniyor, bu yüzden cevaba zaten erişemeyeceksiniz.
9ilsdx 9rvj 0lo

94

Bu işe yarıyor ve dizin testini atlamak verimsiz görünse de, öyle değil: test hemen gerçekleşir listFiles().

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

Sembolik bağların izlenmesini önlemek için güncelleyin:

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
Görünüşe göre, bunda bir hata var. Döngü sırasında başka bir işlem dosyaları silerse, yakalanması ve göz ardı edilmesi gereken bir istisnaya neden olabilir.
Jeff Learman

2
@ 9ilsdx9rvj0lo Snarky olmaktansa, belki sembolik bağları işlemek için bir düzenleme sağlayabilirsiniz. OP , gönderisinde sembolik bağlantılar hakkında hiçbir şey söylemedi . Sadece bir dizin oluşturmak ve silmek. Lütfen "eksik olan birçok şeyi" de listeleyin. Bize yardımcı olun.
Perry Tew

@PerryTew Küstah davranmıyorum. Sadece dış kitaplıklar kullanılmadığı için cevabın daha iyi olduğuna dair yorumunuza tamamen katılmadığımı belirtiyorum. O değil. İnsanların apache commons kullanmasının iyi bir nedeni var: tek bir şeyi kendiniz programlamanıza gerek yok. Sembolik bağlantılar, her şeyi sıfırdan yazmayı özleyeceğiniz şeylerin sadece bir örneğidir.
9ilsdx 9rvj 0lo

2
Bu daha iyi / daha kötü değil, artıları ve eksileri. Dış kitaplıklara güvenmemek bazen önemli bir avantajdır. Elbette denenmiş ve doğrulanmış yazılımı kullanmanın önemli bir faydası vardır. Sorunları dengelemek geliştiriciye bağlıdır. Daha önce bahsedilen ikisi dışında hatalar varsa, kesinlikle onları bilmek isteriz.
Jeff Learman

31

Bu çözümü java 8'de tercih ediyorum:

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

Bu siteden: http://www.baeldung.com/java-delete-directory


2
Tam listeyi oluşturduğundan, sıralı bir kopya oluşturduğundan ve ardından sıralanmış kopya üzerinde yinelediğinden, bunun ölçeklenebilirlik sorunları olabileceğini unutmayın. Hafızanın tükenmez olduğu eski kötü günlerde, bu çok kötü bir fikir olurdu. Kısa ve öz ama uzay (O (N) - O (1)) ve verimlilik (O (N log N) - O (N)) maliyetiyle. Çoğu kullanım durumunda bu önemli değildir.
Jeff Learman

Yukarıda "boşluk O (N) - O (derinlik)"
demeliydim

1
bu zariftir, işe yarar ve harici kitaplıklara bağlı değildir. bayıldım
Leo

Bunun dosya tanıtıcısı sızıntıları sorunu yok mu? Bu örnek yok değil tarafından döndürülen akışı kapatın Files.walk()açıkça API docs belirtilmiştir. Files.list()Örneğin, tarafından döndürülen akışı kapatmazsanız, tutamaçlarınız tükenebilir ve programın çökeceğini biliyorum. Örneğin, stackoverflow.com/q/36990053/421049 ve stackoverflow.com/q/26997240/421049'a bakın .
Garret Wilson


23

Apache Commons-IO'yu kullanarak, tek satırlık bir programı izler:

import org.apache.commons.io.FileUtils;

FileUtils.forceDelete(new File(destination));

Bu (biraz) daha performanslı FileUtils.deleteDirectory.


group: 'commons-io', name: 'commons-io', sürüm: '2. +' - kullanışlı
mike rodent

10

Belirtildiği gibi, Java, dosyaları içeren bir klasörü silemez, bu nedenle önce dosyaları, ardından klasörü silin.

İşte bunu yapmak için basit bir örnek:

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

Veya:

FileUtils.forceDelete(new File(destination));

9

JDK'nın eski sürümleriyle çalışan temel yinelemeli sürümüm:

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

2
Bu, dizini okurken bir G / Ç istisnası varsa bir NullPointerException oluşturur. Kod listFiles(), çağırmak yerine null döndürüp döndürmediğini kontrol etmelidir isDirectory().
mernst

9

Aşağıdakiler için en iyi çözüm budur 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

Guava 21+ kurtarmaya. Yalnızca silinecek dizinin dışına işaret eden sembolik bağlantı yoksa kullanın.

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

(Bu soru Google tarafından iyi dizine eklenmiştir, bu nedenle Guava'yı kullanan diğer kişiler, başka bir yerde diğer yanıtlarla gereksiz olsa bile bu yanıtı bulmaktan mutlu olabilir.)


4

Bu çözümü en çok seviyorum. Üçüncü taraf kitaplığı kullanmaz, bunun yerine Java 7'nin NIO2'sini kullanır .

/**
 * 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

Bir seçenek daha org.springframework.util.FileSystemUtils, dizinin tüm içeriğini yinelemeli olarak silecek Spring'in ilgili yöntemini kullanmaktır .

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

Bu işi yapacak!


2

Bunda

index.delete();

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

sen arıyorsun

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

sonra

index.delete();

Eğer sildikten sonra dosyayı yeniden yaratmakta olduğu bu araçlar File.delete () yapmanız daha sonra kontrol etmek istiyorsanız bir boolean value.So döndürür System.out.println(index.delete());sen alırsanız truedosya silinir o zaman bu araçları

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
               }




        }

dan yapılan yorumlar aşağıda verilmiştir, güncellenmiş cevabı böyledir

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

Alt klasörleriniz varsa, Cemron cevaplarında sorun bulacaksınız. bu nedenle şu şekilde çalışan bir yöntem oluşturmalısınız:

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

2

FileUtils.deleteDirectory'yi kullanabilirsiniz . JAVA, boş olmayan katları File.delete () ile silemez .


1

directry, dosyalara sahipse basitçe silemez, bu nedenle önce içindeki dosyaları sonra dizini silmeniz gerekebilir.

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

Alt dizinler varsa özyinelemeli arama yapabilirsiniz

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

spring-corebağımlılığı kullanabiliriz ;

boolean result = FileSystemUtils.deleteRecursively(file);

1

JDK sınıflarına atıfta bulunan yanıtların çoğu (hatta en son) güveniyor, File.delete()ancak işlem sessizce başarısız olabileceği için bu hatalı bir API'dir. Yöntem belgelerine durumları:
java.io.File.delete()

java.nio.file.FilesSınıfın, bir dosya silinemediğinde deletefırlatma yöntemini tanımladığını unutmayın IOException. Bu, hata bildirimi ve bir dosyanın neden silinemediğini teşhis etmek için kullanışlıdır.

Değiştirilmesi gibi, iyilik etmelidir Files.delete(Path p) dair bir atar IOExceptionbir hata mesajı ile.

Gerçek kod şu şekilde yazılabilir:

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

aşağıdaki gibi deneyebilirsiniz

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

Klasörünüzün içinde alt klasörler varsa, bunları tekrar tekrar silmeniz gerekebilir.


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

    }

Tıkır tıkır çalışıyor . Hem klasör hem de dosyalar için. Salam :)


-1

Başka bölümden kaldır

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

Bu cevaplardan bazıları gereksiz yere uzun görünüyor:

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

Alt dizinler için de çalışır.


-3

Bu işlevi kullanabilirsiniz

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

Tüm kapalı dosyalar içeren bir dizinde sorunsuz çalışır. Ancak açık dosyalarla dizinde denendiğinde çalışmıyor. Açık dosyalardan sonra klasörü silmenin bir yolunu bulmama yardım eder misin
Piyush Rumao

2
Bu, boş olmayan alt dizinleri silmez.
Pang
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.