Java 함수 프로그래밍(11): 디렉터리 훑어보기

디렉토리의 파일을 나열합니다.
파일 클래스의list() 방법으로 디렉터리에 있는 모든 파일의 파일 이름을 쉽게 표시할 수 있습니다.파일 이름뿐만 아니라 파일을 가져오려면listFiles () 방법을 사용하십시오.이것은 매우 간단하다. 어려운 것은 이 되돌아오는 목록을 어떻게 처리하는가이다.우리는 더 이상 전통적인 지루한 외부 교체기를 사용하지 않고 우아한 함수식으로 이 목록을 훑어본다.여기에서 우리는 JDK의 새로운 Closeable Stream 인터페이스와 관련된 고급 함수를 사용해야 한다.
다음 코드는 현재 디렉터리에 있는 모든 파일의 이름을 표시할 수 있습니다.

Files.list(Paths.get("."))
     .forEach(System.out::println);
다른 디렉터리를 열거하고 싶으면'.'액세스하려는 디렉토리의 전체 경로로 바꿉니다.
여기에 먼저 Paths의 get () 방법을 사용하고 문자열을 통해 Path 실례를 만들었습니다.그리고 Files 도구 클래스의list () 방법을 통해 Closable Stream 대상을 얻었습니다. 디렉터리에 있는 모든 파일을 훑어볼 수 있습니다.그런 다음 내부 교체기 forEach () 를 사용하여 파일 이름을 인쇄합니다.먼저 이 코드의 일부 출력 결과를 보겠습니다. 현재 디렉터리에 있는 파일과 하위 디렉터리를 보여 줍니다.

./aSampleFiles.txt
./bin
./fpij
...
현재 디렉터리의 하위 디렉터리만 가져오고 파일이 없으면 filter () 방법을 사용할 수 있습니다.

Files.list(Paths.get("."))
     .filter(Files::isDirectory)
     .forEach(System.out::println);
ilter () 방법은 디렉터리를 파일 흐름에서 선별합니다.우리는 lambda 표현식이 아니라 Files 클래스의 isDirectory 방법의 인용을 전달했다.filter () 방법을 생각해 보세요. boolean 값을 되돌려주는Predicate 형식이 필요합니다. 이 방법이 딱 맞습니다.마지막으로 우리는 디렉터리의 이름을 내부 교체기로 출력했다.프로그램은 현재 디렉터리의 하위 디렉터리를 출력합니다.

./bin
./fpij
./output
...
이렇게 쓰는 것이 훨씬 간단해져서 자바의 오래된 쓰기 방법에 비해 코드를 많이 절약했다.다음은 어떤 패턴과 일치하는 파일을 어떻게 열거하는지 보여 줍니다.
디렉토리에 지정된 파일을 나열합니다.
Java는 파일 이름을 선별하기 위해list() 방법의 변종을 일찌감치 제공했다.이 버전의list() 방법은 FilenameFilter 형식의 매개 변수를 받아들입니다.이 인터페이스는 accept () 방법 하나만 있습니다. 두 가지 인자를 받아들일 수 있습니다. File dir (디렉터리 대표), String name (파일 이름 대표) 입니다.accept () 방법이true를 되돌려주면 이 파일 이름은 되돌아오는 목록에 나타나고false를 되돌려주는 것은 없습니다.우리 이 방법을 실현해 봅시다.
습관적인 방법은 Filename Filter 인터페이스를 실현한 익명 내부 클래스의 실례를list () 방법에 전달하는 것이다.예를 들어, 우리는 어떻게 이런 방식으로 fpij 디렉터리로 되돌아오는지 봅시다.java 파일.

final String[] files =
new File("fpij").list(new java.io.FilenameFilter() {
public boolean accept(final File dir, final String name) {
return name.endsWith(".java");
}
});
System.out.println(files);
이것은 사실 몇 줄의 코드를 쓰는 데 많은 시간을 들여야 한다.이런 코드는 너무 시끄럽다. 대상을 만들고 함수를 호출하며 익명 내부 클래스를 정의하고 클래스에 삽입하는 방법 등이다.우리는 더 이상 이런 고통을 참을 필요가 없다. 단지 두 개의 매개 변수를 받아들여 bollean의 lambda 표현식으로 돌아가면 된다.자바 컴파일러가 남은 일을 해낼 것이다.
앞의 그 예는 간단하게 lambda 표현식으로 익명 내부를 교체하면 되지만 더욱 최적화된 공간이 있다.새로운 DirectoryStream 도구는 우리가 더욱 효율적으로 큰 디렉터리 구조를 훑어보는 데 도움을 줄 수 있다.우리 이런 방법을 시험해 보자.이것은 newDirectoryStream () 방법의 변종으로 추가 필터를 받아들입니다.

Files.newDirectoryStream(
      Paths.get("fpij"), path -> path.toString().endsWith(".java"))
     .forEach(System.out::println);
이렇게 해서 우리는 익명 내부 클래스를 없애고 번거로운 코드를 간결하고 명확하게 만들었다.이 두 버전의 출력 결과는 같다.우리는 지정한 파일을 인쇄할 것이다.
이 코드는 지정된 디렉터리에서만 출력됩니다.java 파일, 다음은 부분 출력 결과입니다.

fpij/Compare.java
fpij/IterateString.java
fpij/ListDirs.java
...
우리는 파일 이름을 바탕으로 파일을 선별할 수 있으며, 또한 파일 속성, 예를 들어 파일이 실행 가능한 파일인지, 읽을 수 있는지, 쓸 수 있는지 등을 통해 쉽게 선별할 수 있다.이렇게 하려면 FileFilter 형식의 매개 변수를 받아들이는 listFiles () 방법이 필요합니다.우리는 익명 내부 클래스를 만드는 것이 아니라lambda 표현식을 사용합니다.현재 디렉터리에 숨겨진 모든 파일을 보여 주는 예를 보십시오.

final File[] files = new File(".").listFiles(file -> file.isHidden());
만약 우리가 매우 큰 디렉터리를 조작한다면, Directorystream을 사용하여 파일 위의 방법을 직접 호출하는 것이 아니라 사용할 수 있다.
listFiles () 방법에 대한 lambda 표현식 서명과 FileFilter 인터페이스의 accept () 방법의 서명은 같습니다.이 lambda 표현식은 File 실례의 매개 변수를 받아들입니다. 이 예에서 매개 변수의 이름은 file입니다.파일이 숨겨진 속성이라면true로 돌아왔습니다. 그렇지 않으면false로 돌아갑니다.
여기는 사실 코드를 다시 간소화할 수 있습니다. 우리는 lambda 표현식을 전달하지 않습니다. 하나의 방법을 전달하면 코드를 더욱 간결하게 보일 수 있습니다.

new File(".").listFiles(File::isHidden);
우리는 먼저 lambda 표현식으로 실현한 다음에 방법을 인용하여 그것을 더욱 간결하게 재구성했다.만약 우리가 다시 새로운 코드를 쓴다면, 당연히 이런 간결한 방식을 채택해야 한다.만약 이런 간결한 실현을 일찍 발견할 수 있다면, 우리는 당연히 그것을 우선적으로 사용해야 한다.'일단 그것을 작동시킨 다음에 최적화(make it work, then make it better)'라는 말이 있다. 코드를 먼저 뛰게 하고 우리가 똑똑히 정리한 후에야 간결성과 성능 등을 고려하여 최적화를 한다.
우리는 하나의 예를 통해 디렉터리에서 지정한 파일을 필터했다.지정한 디렉터리 아래의 하위 디렉터리를 훑어보는 방법을 살펴보겠습니다.

좋은 웹페이지 즐겨찾기