노드 JS 파일 디렉토리 검색 알고리즘

이 게시물에서는 다음 기준을 사용하여 노드 기반 프로그램용 Typescript에서 파일 시스템 검색 알고리즘을 작성할 것입니다.
  • 모든 크기의 파일 트리입니다.
  • 검색할 지정된 디렉토리 이름이 인수로 전달됩니다.
  • 기본적으로 항상 process.cwd()에서 검색을 시작합니다.
  • 처음 발견된 항목을 반환합니다.
  • 반환 값은 찾은 디렉토리에 대한 경로의 문자열이 포함된 배열이거나 찾지 못한 경우 빈 배열이어야 합니다.

  • 시작하다



    가장 먼저 할 일은 새 Node JS 프로젝트를 초기화하는 것입니다. 이를 위해 Yarn 패키지 관리자를 사용합니다.

    yarn init
    
    # You can go ahead and just press enter through each option.
    


    다음으로 할 일은 프로그램을 실행할 수 있도록 몇 가지 개발 종속성을 추가하는 것입니다.

    yarn add -D @types/node ts-node typescript
    


    프로그램을 실행하는 데 사용할 스크립트를 package.json에 추가할 수도 있습니다.

    {
      "name": "file-tree-search",
      "scripts": {
        "fts": "ts-node src/index.ts"
      },
      "devDependencies": {
        "@types/node": "^18.7.16",
        "ts-node": "^10.9.1",
        "typescript": "^4.8.3"
      },
      "license": "MIT"
    }
    


    다음으로 프로그램을 위한 src 디렉토리와 일부 파일을 생성하고 테스트 디렉토리는 검색 알고리즘에서 파일 트리로 테스트할 수 있는 일부 디렉토리와 빈 파일이 될 것입니다.

    # Create directories
    mkdir src test test/hello test/world
    



    # Create files
    touch src/index.ts src/search.ts test/random.txt test/hello/another.txt test/world/pizza.txt
    


    검색 알고리즘 만들기



    이제 search.ts에 검색 알고리즘을 작성할 수 있습니다.

    import { readdirSync, statSync } from "fs";
    import { join } from "path";
    
    export const findDirectory = (
      searchName: string,
      startDirectory = [process.cwd()]
    ): string => {
      const scanStartDir = readdirSync(join(...startDirectory));
      const filteredScan = scanStartDir.filter((dir) =>
        isDir(join(...[...startDirectory, dir]))
      );
      if (filteredScan.includes(searchName)) {
        return join(...[...startDirectory, searchName]);
      } else if (filteredScan.length === 0) {
        return "";
      } else {
        let subScanFound = "";
        filteredScan.every((dir) => {
          const result = findDirectory(searchName, [...startDirectory, dir]);
          if (result.length > 0) {
            subScanFound = result;
            return false;
          }
          return true;
        });
        return subScanFound;
      }
    };
    
    const isDir = (path: string): boolean => {
      try {
        return statSync(path).isDirectory();
      } catch (e) {
        return false;
      }
    };
    


    검색 알고리즘 설명



    먼저 파일 시스템과 상호 작용하기 위해 표준 노드 라이브러리에서 제공하는 기능이 필요합니다. readdirSync를 가져와서 어떤 파일이 디렉토리에 속하는지 검색하고 statSync를 가져와 개별 파일에 대한 정보를 얻습니다. 파일 시스템으로 작업할 때 "path" 라이브러리는 파일 경로를 처리하는 운영 체제에 구애받지 않는 방법을 제공합니다. 예를 들어 Windows와 MacOS의 경로는 다르기 때문에 프로그램이 일종의 파일 경로 구조와 함께 작동하기를 원합니다. 문자열을 결합하여 경로를 만들기 위해 join 에서 "path" 를 가져옵니다.
    findDirectory 검색 기능에 대한 두 가지 인수는 다음과 같습니다.
  • searchName : 검색할 디렉토리 이름의 문자열입니다.
  • startDirectory : 트리 아래로 내려가는 검색을 시작할 디렉토리. 기본적으로 실행 중인 노드 프로세스의 현재 작업 디렉토리를 가져오므로 [process.cwd()]를 전달합니다. 사용자는 원하는 경우 다른 것을 전달할 수 있습니다(아마도 __dirname에서 검색하는 것이 함수 사용자에게 유용할 것입니다). 나중에 경로를 구성하는 데 사용할 수 있도록 이것을 문자열 배열로 나타냅니다.

  • 가장 먼저 할 일은 전달된 파일startDirectory을 읽은 다음 해당 결과를 필터링하여 결과에서 기본 파일을 제거하는 것입니다. 우리는 디렉터리를 검색하고 있으므로 파일을 제외하도록 결과 범위를 좁히는 방법입니다.

    const scanStartDir = readdirSync(join(...startDirectory))
    const filteredScan = scanStartDir.filter((dir) => isDir(join(...[...startDirectory, dir])))
    


    필터를 단순하게 유지하기 위해 추상isDir 함수를 만듭니다. 이 함수는 단순히 path 인수를 취하고 개별 파일이 디렉토리인지 여부에 대한 부울을 반환합니다. Node 표준 라이브러리에는 파일에 대한 정보를 얻기 위한 편리한statSync이 있습니다. true 또는 false를 반환하는 isDirectory() 함수를 사용합니다.

    필터링된 결과로 이제 조건 평가를 시작할 수 있습니다. 우리의 findDirectory 함수는 재귀적으로 작성됩니다. 즉, 원래 문제의 하위 집합을 해결하기 위해 내부적으로 자신을 호출합니다.

    첫 번째 조건은 검색을 중지할 수 있도록 검색 중인 디렉터리를 찾았다는 기본 사례입니다.

    if (filteredScan.includes(searchName)) {
      return join(...[...startDirectory, searchName])
    }
    


    또한 검색 중인 현재 디렉터리에 디렉터리가 포함되어 있지 않아 검색을 중지할 수 있는 보조 기본 사례도 있습니다.

    else if (filteredScan.length === 0) {
      return "";
    }
    


    검색을 중지해야 하는 조건, 즉 기본 사례와는 별도로 필터링된 검색 결과의 모든 디렉터리를 계속 검색해야 합니다. 여기에서 재귀가 발생합니다.

    else {
      let subScanFound = "";
      filteredScan.every((dir) => {
        const result = findDirectory(searchName, [...startDirectory, dir]);
        if (result.length > 0) {
          subScanFound = result;
          return false;
        }
        return true;
      });
      return subScanFound;
    }
    

    좋은 웹페이지 즐겨찾기