Java, 파일이 아닌 디렉토리의 하위 디렉토리 만 나열


100

Java에서 디렉토리의 하위 디렉토리 만 나열하려면 어떻게합니까?

java.io.File 기능을 사용하고 싶습니다.이 작업을 수행하는 데 Java에서 가장 좋은 방법은 무엇입니까?

답변:


141

File 클래스를 사용 하여 디렉토리를 나열 할 수 있습니다 .

File file = new File("/path/to/directory");
String[] directories = file.list(new FilenameFilter() {
  @Override
  public boolean accept(File current, String name) {
    return new File(current, name).isDirectory();
  }
});
System.out.println(Arrays.toString(directories));

최신 정보

이 게시물에 대한 작성자의 의견은 더 빠른 방법을 원했고 여기에 훌륭한 토론이 있습니다. Java에서 디렉토리 목록을 빠르게 검색하는 방법?

원래:

  1. 파일 구조를 제어한다면 그 상황에 빠지지 않으려 고 노력할 것입니다.
  2. Java NIO.2에서는 디렉토리 함수를 사용하여 더 큰 확장을 허용하는 반복자를 반환 할 수 있습니다. 디렉토리 스트림 클래스는 디렉토리의 항목을 반복하는 데 사용할 수있는 객체입니다.

안녕하세요, 답장 해 주셔서 감사합니다. 하지만 디렉토리의 모든 항목을 반복 할 필요는 없습니다. 디렉토리에서 하위 디렉토리를 직접 나열해야합니다. B'coz 디렉토리에 파일이 많고 하위 디렉토리가 거의 없으므로 isDirectory ()를 확인하는 데 시간이 많이 걸립니다. 다른 방법으로 답장 해주세요.
Lokesh Paunikar

특히 내 게시물을 업데이트하여 질문에 대한 Jon Skeet의 의견을 살펴 보았습니다. 그리고 Java NIO 2 이후의 NIO 응답에는 디렉토리 스트림을 반환하는 디렉토리 함수에 대한 반복기가 있습니다.
Mohamed Mansour

어떤 Skeet 코멘트를 언급하고 있습니까? 여기서 더 나은 답변은 무엇입니까?
Stealth Rabbi

107

매우 간단한 Java 8 솔루션 :

File[] directories = new File("/your/path/").listFiles(File::isDirectory);

FileFilter를 사용하는 것과 동일합니다 (이전 Java에서도 작동).

File[] directories = new File("/your/path/").listFiles(new FileFilter() {
    @Override
    public boolean accept(File file) {
        return file.isDirectory();
    }
});

4
이 경우 이중 콜론은 어떻게 ::작동합니까?
snickers10m

다른 대답은 FileFilter를 사용하지 않으므로 메서드 참조를 사용하지 않고 동등한 버전을 추가했습니다. 메서드 참조에 대한 자세한 내용은이 SO 질문 또는이 기사를 참조하십시오 .
headsvk 2015

이것은 하위 디렉토리 또는 / your / path / 바로 아래의 디렉토리를 얻습니까?
amadain


14

@Mohamed Mansour 당신은 거의 거기에있었습니다 ... 당신이 사용하고 있던 "dir"인수는 실제로 현재의 경로이므로 항상 true를 반환합니다. 하위 디렉토리가 하위 디렉토리인지 확인하려면 해당 하위 디렉토리를 테스트해야합니다.

File file = new File("/path/to/directory");
String[] directories = file.list(new FilenameFilter() {
  @Override
  public boolean accept(File current, String name) {
    return new File(current, name).isDirectory();
  }
});
System.out.println(Arrays.toString(directories));

7

Java 7 및 NIO.2를 사용하는 솔루션에 관심이있는 경우 다음과 같이 진행할 수 있습니다.

private static class DirectoriesFilter implements Filter<Path> {
    @Override
    public boolean accept(Path entry) throws IOException {
        return Files.isDirectory(entry);
    }
}

try (DirectoryStream<Path> ds = Files.newDirectoryStream(FileSystems.getDefault().getPath(root), new DirectoriesFilter())) {
        for (Path p : ds) {
            System.out.println(p.getFileName());
        }
    } catch (IOException e) {
        e.printStackTrace();
    }

3
ArrayList<File> directories = new ArrayList<File>(
    Arrays.asList(
        new File("your/path/").listFiles(File::isDirectory)
    )
);

안녕하세요, StackOverflow에 오신 것을 환영합니다! 답변에 대해 조금 자세히 설명해 주시겠습니까? 코드 조각의 흥미로운 부분을 설명하거나 추가 읽기를 위해 문서에 연결하는 것과 같은가요?
Richard-Degenne 19

완전한 Canonical Path를 가진 File 객체를 제공하므로 정답이어야합니다. 이 오래된 될 수 있지만, 그것의 가치는이 지적
제로 Dungog

2

Java 7 및 NIO에도 관심이있는 사람들을 위해 위의 @voo 답변에 대한 대안 솔루션이 있습니다. 호출 하는 try-with-resourcesFiles.find() 와 디렉터리를 필터링하는 데 사용되는 람다 함수를 사용할 수 있습니다.

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.stream.Stream;


final Path directory = Paths.get("/path/to/folder");

try (Stream<Path> paths = Files.find(directory, Integer.MAX_VALUE, (path, attributes) -> attributes.isDirectory())) {
    paths.forEach(System.out::println);
} catch (IOException e) {
    ...
}

람다 함수를 변경하여 이름으로 디렉터리를 필터링 할 수도 있습니다.

(path, attributes) -> attributes.isDirectory() && path.toString().contains("test")

또는 날짜 별 :

final long now = System.currentTimeMillis();
final long yesterday = new Date(now - 24 * 60 * 60 * 1000L).getTime();

// modified in the last 24 hours
(path, attributes) -> attributes.isDirectory() && attributes.lastModifiedTime().toMillis() > yesterday

2

java.io.File 기능을 사용하고 싶습니다.

2012 년 (질문 날짜) 예, 오늘은 아닙니다. java.nio이러한 요구 사항에는 API가 선호되어야합니다.

너무 많은 답변으로 끔찍하지만 내가 사용하는 간단한 방법은 Files.walk().filter().collect().

전 세계적으로 두 가지 접근 방식이 가능합니다.

1) 제한 Files.walk(Path start, )이 없습니다.maxDepth

2) Files.walk(Path start, int maxDepth, FileVisitOption... options)설정할 수 있습니다.

깊이 제한을 지정하지 않으면 다음을 제공합니다.

Path directory = Paths.get("/foo/bar");

try {
    List<Path> directories =
            Files.walk(directory)
                 .filter(Files::isDirectory)
                 .collect(Collectors.toList());
} catch (IOException e) {
    // process exception
}

레거시 이유로 인해 목록을 File가져와야하는 map(Path::toFile)경우 수집하기 전에 작업을 추가하면 됩니다.

Path directory = Paths.get("/foo/bar");

try {
    List<File> directories =
            Files.walk(directory)
                 .filter(Files::isDirectory)
                 .map(Path::toFile)
                 .collect(Collectors.toList());
} catch (IOException e) {
    // process exception
}

또한이 Files.list(Path)아마와 동일하다 Files.walk(Path,1).
David L.

@David L Indeed Files.list(Path)는 반복적으로 폴더를 반복하고 싶지 않다면 공정한 대안입니다. 폴더를 재귀 적으로 반복하려면 walk()더 적합합니다.
davidxxx

1

나를 위해 일한 솔루션이 답변 목록에서 누락되었습니다. 따라서이 솔루션을 여기에 게시하고 있습니다.

File[]dirs = new File("/mypath/mydir/").listFiles((FileFilter)FileFilterUtils.directoryFileFilter());

여기 org.apache.commons.io.filefilter.FileFilterUtils에서는 Apache commons-io-2.2.jar에서 사용했습니다. 문서는 https://commons.apache.org/proper/commons-io/javadocs/api-2.2/org/apache/commons/io/filefilter/FileFilterUtils.html에서 볼 수 있습니다.


0

시작 디렉토리가 String

  1. String경로를 매개 변수로 사용 하는 메소드를 작성하십시오 . 방법에서 :
  2. 시작 디렉터리를 기반으로 새 파일 개체 만들기
  3. listFiles메소드를 사용하여 현재 디렉토리에서 파일 배열 가져 오기
  4. 파일 배열 루프
    1. 파일 인 경우 계속 반복
    2. 디렉토리 인 경우 이름을 인쇄 하고이 새 디렉토리 경로에서 반복 합니다.

안녕하세요, 답장 해 주셔서 감사합니다. 하지만 디렉토리의 모든 항목을 반복 할 필요는 없습니다. 디렉토리에서 하위 디렉토리를 직접 나열해야합니다. B'coz 디렉토리에 파일이 많고 하위 디렉토리가 거의 없으므로 isDirectory ()를 확인하는 데 시간이 많이 걸립니다. 다른 방법으로 답장 해주세요.
Lokesh Paunikar

0

여기 내 코드에 대한 해결책이 있습니다. 방금 첫 번째 답변에서 약간의 변경 을했습니다 . 그러면 원하는 디렉토리의 모든 폴더가 한 줄씩 나열됩니다.

try {
            File file = new File("D:\\admir\\MyBookLibrary");
            String[] directories = file.list(new FilenameFilter() {
              @Override
              public boolean accept(File current, String name) {
                return new File(current, name).isDirectory();
              }
            });
            for(int i = 0;i < directories.length;i++) {
                if(directories[i] != null) {
                    System.out.println(Arrays.asList(directories[i]));

                }
            }
        }catch(Exception e) {
            System.err.println("Error!");
        }
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.