[java] Java 디렉토리의 파일을 어떻게 반복합니까?

모든 하위 디렉토리의 파일을 포함하여 디렉토리의 모든 파일 목록을 가져와야합니다. Java로 디렉토리 반복을 수행하는 표준 방법은 무엇입니까?



답변

File#isDirectory()주어진 파일 (경로)이 디렉토리인지 테스트 하는 데 사용할 수 있습니다 . 이 인 경우 true동일한 메소드를 다시 호출하여 File#listFiles()결과를 얻습니다. 이것을 재귀 라고 합니다.

기본 시작 예는 다음과 같습니다.

public static void main(String... args) {
    File[] files = new File("C:/").listFiles();
    showFiles(files);
}

public static void showFiles(File[] files) {
    for (File file : files) {
        if (file.isDirectory()) {
            System.out.println("Directory: " + file.getName());
            showFiles(file.listFiles()); // Calls same method again.
        } else {
            System.out.println("File: " + file.getName());
        }
    }
}

이것은 StackOverflowError트리가 JVM 스택이 보유 할 수있는 것보다 깊을 때에 민감합니다 . 대신 반복적 인 접근 방식이나 꼬리 재귀 를 사용하고 싶을 수도 있지만 다른 주제입니다.)


답변

Java 1.7을 사용중인 경우 다음을 사용할 수 있습니다. java.nio.file.Files.walkFileTree(...) .

예를 들면 다음과 같습니다.

public class WalkFileTreeExample {

  public static void main(String[] args) {
    Path p = Paths.get("/usr");
    FileVisitor<Path> fv = new SimpleFileVisitor<Path>() {
      @Override
      public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
          throws IOException {
        System.out.println(file);
        return FileVisitResult.CONTINUE;
      }
    };

    try {
      Files.walkFileTree(p, fv);
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

}

Java 8을 사용하는 경우 다음과 함께 스트림 인터페이스를 사용할 수 있습니다 java.nio.file.Files.walk(...).

public class WalkFileTreeExample {

  public static void main(String[] args) {
    try (Stream<Path> paths = Files.walk(Paths.get("/usr"))) {
      paths.forEach(System.out::println);
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

}


답변

Apache Commons 의 FileUtils 클래스, 특히 iterateFiles를 확인하십시오 .

지정된 디렉토리 (및 선택적으로 서브 디렉토리)의 파일을 반복 할 수 있습니다.


답변

Java 7+의 경우 https://docs.oracle.com/javase/7/docs/api/java/nio/file/DirectoryStream.html있습니다.

Javadoc에서 가져온 예제 :

List<Path> listSourceFiles(Path dir) throws IOException {
   List<Path> result = new ArrayList<>();
   try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir, "*.{c,h,cpp,hpp,java}")) {
       for (Path entry: stream) {
           result.add(entry);
       }
   } catch (DirectoryIteratorException ex) {
       // I/O error encounted during the iteration, the cause is an IOException
       throw ex.getCause();
   }
   return result;
}


답변

사용 org.apache.commons.io.FileUtils

File file = new File("F:/Lines");
Collection<File> files = FileUtils.listFiles(file, null, true);
for(File file2 : files){
    System.out.println(file2.getName());
} 

서브 디렉토리에서 파일을 원하지 않으면 false를 사용하십시오.


답변

그것은 나무이기 때문에 재귀는 친구입니다. 부모 디렉토리로 시작하고 메소드를 호출하여 자식 파일 배열을 가져옵니다. 자식 배열을 반복합니다. 현재 값이 디렉토리이면 메소드의 재귀 호출에 전달하십시오. 그렇지 않으면 리프 파일을 적절하게 처리하십시오.


답변

언급했듯이 이것은 재귀 문제입니다. 특히, 당신은보고 싶어 할 수 있습니다

listFiles() 

자바 파일 API 에서 here . 디렉토리에있는 모든 파일의 배열을 리턴합니다. 이것과 함께 사용

isDirectory()

더 재귀가 필요한지 확인하는 것이 좋습니다.