하나의 라이너 솔루션-디렉토리가 아닌 디렉토리의 모든 파일 삭제


201

ABC 디렉토리 내의 모든 파일을 삭제하고 싶습니다.

내가 시도 FileUtils.deleteDirectory(new File("C:/test/ABC/"));하면 폴더 ABC도 삭제됩니다.

디렉토리 내부의 파일을 삭제할 수 있지만 디렉토리는 아닌 하나의 라이너 솔루션이 있습니까?


2
.deleteDirectory (이름이 암시하더라도)는 디렉토리를 삭제하는 데 사용되기 때문입니다. 파일이 디렉토리가 아닌 경우 디렉토리를 가져옵니다.
user1534664

FileUtils 클래스 내에서 디렉토리 대신 파일을 삭제하는 다른 함수를 찾으십시오.
user1534664


1
왜 특별히 하나의 라이너가 필요합니까? 타사 라이브러리 방법은 재귀 적으로 만 수행하므로 성능은 기준이 될 수 없습니다. 동일한 성능을 제공합니까?
Rohit Jain

1
디렉토리를 삭제 한 다음 다시 작성하면됩니다. 사용하는 rm -rf directory; mkdir directory것이을 사용하는 것보다 빠릅니다 FileUtils.cleanDirectory.
Joshua Pinter

답변:


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

FileUtils.cleanDirectory(directory); 

동일한 파일에서이 방법을 사용할 수 있습니다. 또한 하위 폴더와 파일 아래의 모든 하위 폴더를 재귀 적으로 삭제합니다.

문서 : org.apache.commons.io.FileUtils.cleanDirectory


49
사람들이 이걸 보지 못하게하는 것도 좋은 일입니다. 가져 오기는 다음과 같습니다. import org.apache.commons.io.FileUtils;
Paul Gregoire

5
왜 가져 오기를 찾을 수 없는지 찾아봐야합니다. apache.org에서 다운로드 해야하기 때문 입니다.
Tomáš Zato-복원 모니카

예쁜 해결책. gradle로이 라이브러리를 확인하십시오 : "commons-io : commons-io : +"컴파일
Leo Nguyen

1
Gradle 종속성 -컴파일 그룹 : 'commons-io', 이름 : 'commons-io', 버전 : '2.5'
Jaydev

우리는 호출하는 것이을 rm -rf directory사용하는 것보다 훨씬 효율적이라는 것을 알았 습니다 FileUtils.cleanDirectory.
Joshua Pinter

267

당신은 좋아합니까?

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

디렉토리가 아닌 파일 만 삭제합니다.


65
이것은 외부 라이브러리를 사용하지 않기 때문에 definitley가 더 나은 대답입니다!
AlexWien

10
@ amar 그러나 그때조차도 : 표준 방법이있을 때 절대적으로 동일한 일을하는 외부 방법을 사용할 이유가 없습니다. 언젠가는 lib를 제거하고 싶거나 lib가 더 이상 지원되지 않거나 라이센스 이유로 인해 lib를 사용할 수 없습니다. 다른 많은 것들)
AlexWien

10
루트 "dir"디렉토리 내에 서브 디렉토리가있는 경우 모든 것이 삭제되지 않습니다.
Tiago

2
@TiagoT 사실, 비어 있지 않은 하위 디렉토리는 삭제되지 않습니다.
피터 로리

4
for(File file: dir.listFiles()).... for (File file : new java.io.File("C:\\DeleteMeFolder").listFiles())...
Hartmut P.

62

Peter Lawrey의 답변은 간단하고 특별한 것에 의존하지 않기 때문에 훌륭합니다. 하위 디렉토리와 그 내용도 제거하는 것이 필요한 경우 재귀를 사용하십시오.

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

하위 디렉토리와 그 내용 (질문의 일부)을 아끼려면 다음과 같이 수정하십시오.

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

또는 한 줄 솔루션을 원했기 때문에 :

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

그런 사소한 작업을 위해 외부 라이브러리를 사용하는 것은 어쨌든이 라이브러리가 필요하지 않은 한 좋은 아이디어가 아닙니다.이 경우 기존 코드를 사용하는 것이 좋습니다. 어쨌든 Apache 라이브러리를 사용하고있는 것처럼 보이므로 그 FileUtils.cleanDirectory()방법을 사용하십시오 .


1
반면에 외부 라이브러리를 처음 사용하는 사람이 없다면 다른 사람들이 해당 외부 라이브러리에서 비슷한 동작을 기대할 가능성이 적고, 외부 라이브러리를 볼 가능성이 적습니다 ... 여기서 발명되지 않았습니까? 라이브러리가 응집력 있고 프로젝트에 쉽게 추가 할 수 있다면 거의 항상 라이브러리를 추가하는 것을 선호합니다.
JB Rainsberger

33

자바 8 스트림

이렇게하면 ABC 에서 파일 만 삭제됩니다 (하위 디렉토리는 변경되지 않음).

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

이렇게하면 ABC (및 하위 디렉토리) 에서 파일 만 삭제됩니다 .

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

^이 버전은 IOException 처리가 필요합니다


1
두 번째는 하위 디렉토리를 삭제하지 않습니다 (테스트 됨)
edwise

1
@edwise 예, ABC의 모든 파일과 하위 디렉토리의 모든 파일을 삭제합니다. 영어는 조금 모호합니다.
NonlinearFruit

11

또는 Java 8에서 이것을 사용하려면 :

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

예외 처리가 너무 부피가 큰 것은 유감입니다. 그렇지 않으면 하나의 라이너가됩니다 ...


어떻게 그 파일이 알고 IS 실제로 디렉토리가 아닌 파일을?
Stephan

1
또한 디렉토리를 삭제하므로 주제의 문제에 대한 해결책이 아닙니다.
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

폴더 자체가 아닌 폴더의 모든 내용, 하위 디렉토리 포함을 삭제하는 또 다른 Java 8 스트림 솔루션.

용법:

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

그리고 코드 :

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 또는 Files.delete와 관련된 모든 스트림 솔루션의 문제점은 이러한 메소드가 스트림에서 처리하기 어려운 IOException을 발생 시킨다는 것입니다.

가능한 한 더 간결한 솔루션을 만들려고했습니다.


그런 다음 walk 함수에서 null을 반환하면 빈 스트림 (Stream.empty ())을 반환하는 것이 좋습니다. 더 깨끗하고 함수는 항상 스트림을 반환합니다. 가능하면 널을 피해야합니다.
kaba713

덕분에, 나는 당신의 제안에 답 개선
하이 잭

2

디렉토리에서 모든 파일을 삭제하려면 "C : \ Example"이라고 말하십시오.

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 -rf보다 성능 이 훨씬 뛰어 났습니다 FileUtils.cleanDirectory.

한 줄짜리 솔루션이 아니라 광범위한 벤치마킹 후 사용이을 사용 rm -rf하는 것보다 여러 배 더 빠름을 발견했습니다 FileUtils.cleanDirectory.

물론 작거나 간단한 디렉토리가 있다면 중요하지 않지만 우리의 경우에는 기가 바이트와 깊게 중첩 된 하위 디렉토리가있어 10 분 이상 걸리고 FileUtils.cleanDirectory1 분 밖에 걸리지 않습니다 rm -rf.

이를 수행하기위한 대략적인 Java 구현은 다음과 같습니다.

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

}

크거나 복잡한 디렉토리를 다루는 경우 시도해 볼 가치가 있습니다.


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

모든 파일을 삭제하려면 제거

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

그것이 효과가 있다고 진술하십시오.


0

나는 이것이 효과가 있다고 생각합니다 (NonlinearFruit 이전 답변을 기반으로).

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

건배!

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.