Dizindeki tüm dosyaları sil (dizinde değil) - bir astar çözümü


202

ABC dizini içindeki tüm dosyaları silmek istiyorum.

Onunla denediğimde FileUtils.deleteDirectory(new File("C:/test/ABC/"));ABC klasörünü de siler.

Dizin içindeki dosyaları silebilir, ancak dizin içindeki dosyaları silebileceğim tek bir çözüm var mı?


2
Bu çünkü .deleteDirectory (hatta adı ima eder) dizinin silinmesi için kullanılır. Dosya bir dizin değilse içinde bulunduğu dizini alır.
user1534664

FileUtils sınıfında, dizinin yerine dosyaları silen diğer işlevleri aramayı deneyin.
user1534664


1
Neden özellikle bir astara ihtiyacınız var? Performans ölçüt olamaz, çünkü herhangi bir 3. taraf kütüphane yöntemi bunu sadece tekrarlı olarak yapar. Size aynı performansı verir mi?
Rohit Jain

1
Yapabileceğiniz bir şey, dizini silmek ve sonra yeniden oluşturmaktır. Kullanmanın kullanmaktan rm -rf directory; mkdir directorydaha hızlı olduğunu gördük FileUtils.cleanDirectory.
Joshua Pinter

Yanıtlar:


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

FileUtils.cleanDirectory(directory); 

Aynı dosyada bu yöntem vardır. Bu işlem aynı zamanda tüm alt klasörleri ve bunların altındaki dosyaları tekrar tekrar siler.

Dokümanlar: org.apache.commons.io.FileUtils.cleanDirectory


49
Güzel, aynı zamanda insanların bunu aramak zorunda kalmaması için; İşte içe aktarma: import org.apache.commons.io.FileUtils;
Paul Gregoire

5
İçe aktarmanın neden bulunamadığını hala araştırmam gerekiyor. Çünkü apache.org'dan indirmeniz gerekiyor .
Tomáš Zato - Monica'yı

güzel bir çözüm. Bu kütüphaneyi dereceyle kontrol edin: "commons-io: commons-io: +" derleyin
Leo Nguyen

1
Dereceye bağımlılık - derleme grubu: 'commons-io', isim: 'commons-io', sürüm: '2.5'.
Jaydev

Not, aramanın rm -rf directorykullanmaktan çok daha verimli olduğunu gördük FileUtils.cleanDirectory.
Joshua Pinter

269

Şunu mu demek istediniz?

for(File file: dir.listFiles()) 
    if (!file.isDirectory()) 
        file.delete();

Bu sadece dosyaları siler, dizinleri silmez.


65
Bu harici bir lib kullanmadığı için definitley daha iyi cevaptır!
AlexWien

10
@ amar ama o zaman bile: standart bir yöntem olduğunda, absolutley aynı şeyi yapan harici bir yöntem kullanmanın bir nedeni yoktur. Bir gün lib'den kurtulmak isteyebilir veya lib artık desteklenmemektedir veya lib'i lisans nedenleriyle vb. Kullanmasına izin verilmemektedir. (Bu, bu belirli lib için bir sorun olmayabilir, ancak birçok diğerleri)
AlexWien

10
Kök "dir" dizininde alt dizinleriniz varsa, bu her şeyi silemez.
Tiago

2
@TiagoT Doğru, bu boş olmayan alt dizinleri silmez.
Peter Lawrey

4
for(File file: dir.listFiles())muhtemelen .... anlamına gelir for (File file : new java.io.File("C:\\DeleteMeFolder").listFiles())...
Hartmut P.

63

Peter Lawrey'in cevabı harika çünkü basit ve özel bir şeye bağlı değil ve bunu yapmanın yolu. Alt dizinleri ve içeriklerini de kaldıran bir şeye ihtiyacınız varsa özyineleme kullanın:

void purgeDirectory(File dir) {
    for (File file: dir.listFiles()) {
        if (file.isDirectory())
            purgeDirectory(file);
        file.delete();
    }
}

Alt dizinleri ve içeriklerini (sorunuzun bir parçası) yedeklemek için aşağıdaki gibi değiştirin:

void purgeDirectoryButKeepSubDirectories(File dir) {
    for (File file: dir.listFiles()) {
        if (!file.isDirectory())
            file.delete();
    }
}

Veya tek satırlık bir çözüm istediğiniz için:

for (File file: dir.listFiles())
    if (!file.isDirectory())
        file.delete();

Bu tür önemsiz bir görev için harici bir kütüphane kullanmak, başka bir şey için bu kütüphaneye ihtiyaç duymadıkça iyi bir fikir değildir, bu durumda mevcut kodun kullanılması tercih edilir. Yine de Apache kütüphanesini kullandığınız anlaşılıyor, bu yüzden onun FileUtils.cleanDirectory()yöntemini kullanın .


1
Öte yandan, dış kütüphaneyi ilk kullanan kimse yoksa, o zaman başkalarının bu dış kütüphanede benzer davranışlar bulmasını beklemesi daha az olasıdır ve oraya bakma olasılığı daha azdır ... Burada icat edilmedi mi? Kütüphane uyumlu ve projeme eklenmesi kolaysa, neredeyse her zaman kütüphaneyi eklemeyi tercih ederim.
JB Rainsberger

33

Java 8 Akışı

Bu yalnızca ABC'deki dosyaları siler (alt dizinlere dokunulmaz):

Arrays.stream(new File("C:/test/ABC/").listFiles()).forEach(File::delete);

Bu yalnızca ABC'deki dosyaları (ve alt dizinleri) siler :

Files.walk(Paths.get("C:/test/ABC/"))
                .filter(Files::isRegularFile)
                .map(Path::toFile)
                .forEach(File::delete);

^ Bu sürüm IOException'ın kullanılmasını gerektirir


1
İkincisi alt dizinleri silmez (test edildi)
edwise

1
@ edwise Evet, ABC'deki tüm dosyaları ve alt dizinlerdeki tüm dosyaları siler. İngilizler biraz belirsiz.
NonlinearFruit

11

Veya bunu Java 8'de kullanmak için:

try {
  Files.newDirectoryStream( directory ).forEach( file -> {
    try { Files.delete( file ); }
    catch ( IOException e ) { throw new UncheckedIOException(e); }
  } );
}
catch ( IOException e ) {
  e.printStackTrace();
}

İstisna işlemenin bu kadar hantal olması üzücü, aksi takdirde bir astar olurdu ...


Nasıl bu dosya biliyor musunuz IS aslında ve bir dizin bir dosya?
Stephan

1
Ayrıca dizini de siler, bu yüzden konuya bir çözüm değildir
Marx

5
public class DeleteFile {
    public static void main(String[] args) {
        String path="D:\test"; 
        File file = new File(path);
        File[] files = file.listFiles(); 
        for (File f:files) 
        {if (f.isFile() && f.exists) 
            { f.delete();
system.out.println("successfully deleted");
            }else{
system.out.println("cant delete a file due to open or error");
} }  }}

2

Bir klasörün tüm içeriğini silmek için başka bir Java 8 Stream çözümü, alt dizinler dahil, ancak klasörün kendisini değil.

Kullanımı:

Path folder = Paths.get("/tmp/folder");
CleanFolder.clean(folder);

ve kod:

public interface CleanFolder {
    static void clean(Path folder) throws IOException {

        Function<Path, Stream<Path>> walk = p -> {
            try { return Files.walk(p);
        } catch (IOException e) {
            return Stream.empty();
        }};

        Consumer<Path> delete = p -> {
            try {
                Files.delete(p);
            } catch (IOException e) {
            }
        };

        Files.list(folder)
            .flatMap(walk)
            .sorted(Comparator.reverseOrder())
            .forEach(delete);
    }
}

Files.walk veya Files.delete içeren her akış çözümüyle ilgili sorun, bu yöntemlerin akışlarda işlemek için bir acı olan IOException oluşturmasıdır.

Mümkün olduğunca özlü bir çözüm yaratmaya çalıştım.


Daha sonra, yürüme işlevinde bir null döndürme işlevi boş bir dere (Stream.empty ()) döndürmek daha iyi olacaktır. Daha temiz ve işlev her zaman bir akış döndürür. Mümkün olduğunda null değerinden kaçınılmalıdır.
kaba713

Teşekkürler, ben Öneriniz ile cevap geliştirilmiş
kaçırmak

2

Dizindeki tüm dosyaları silmek için "C: \ Örnek" deyin

File file = new File("C:\\Example");      
String[] myFiles;    
if (file.isDirectory()) {
    myFiles = file.list();
    for (int i = 0; i < myFiles.length; i++) {
        File myFile = new File(file, myFiles[i]); 
        myFile.delete();
    }
}

2

rm -rfoldu çok daha daha fazla ölçülebilir FileUtils.cleanDirectory.

Tek rm -rfkatmanlı bir çözüm değil, kapsamlı bir kıyaslamadan sonra, kullanımın kullanmaktan çok daha hızlı olduğunu gördük FileUtils.cleanDirectory.

Tabii ki, küçük veya basit bir dizininiz varsa, önemli değil, ancak bizim durumumuzda, birden fazla gigabayt ve 10 dakikadan fazla FileUtils.cleanDirectoryve sadece 1 dakika sürecek derin iç içe geçmiş alt dizinlerimiz vardı rm -rf.

İşte bunu yapmak için kaba Java uygulaması:

// Delete directory given and all subdirectories and files (i.e. recursively).
//
static public boolean clearDirectory( File file ) throws IOException, InterruptedException {

    if ( file.exists() ) {

        String deleteCommand = "rm -rf " + file.getAbsolutePath();
        Runtime runtime = Runtime.getRuntime();

        Process process = runtime.exec( deleteCommand );
        process.waitFor();

        file.mkdirs(); // Since we only want to clear the directory and not delete it, we need to re-create the directory.

        return true;
    }

    return false;

}

Büyük veya karmaşık dizinlerle uğraşıyorsanız denemeye değer.


1
package com;
import java.io.File;
public class Delete {
    public static void main(String[] args) {

        String files; 
        File file = new File("D:\\del\\yc\\gh");
        File[] listOfFiles = file.listFiles(); 
        for (int i = 0; i < listOfFiles.length; i++) 
        {
            if (listOfFiles[i].isFile()) 
            {
                files = listOfFiles[i].getName();
                System.out.println(files);
                if(!files.equalsIgnoreCase("Scan.pdf"))
                {
                    boolean issuccess=new File(listOfFiles[i].toString()).delete();
                    System.err.println("Deletion Success "+issuccess);
                }
            }
        }
    }
}

Tüm dosyaları silmek istiyorsanız kaldırın

if(!files.equalsIgnoreCase("Scan.pdf"))

ifadesi işe yarayacaktır.


0

Bence bu işe yarayacaktır (NonlinearFruit önceki cevaba dayanarak):

Files.walk(Paths.get("C:/test/ABC/"))
                .sorted(Comparator.reverseOrder())
                .map(Path::toFile)
                .filter(item -> !item.getPath().equals("C:/test/ABC/"))
                .forEach(File::delete);

Şerefe!

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.