your programing

Node.js의 디렉토리에있는 모든 파일의 이름 목록을 어떻게 얻습니까?

lovepro 2020. 9. 28. 09:52
반응형

Node.js의 디렉토리에있는 모든 파일의 이름 목록을 어떻게 얻습니까?


Node.js를 사용하여 디렉토리에있는 모든 파일의 이름 목록을 얻으려고합니다. 파일 이름 배열 인 출력을 원합니다. 어떻게 할 수 있습니까?


fs.readdir또는 fs.readdirSync메서드를 사용할 수 있습니다 .

fs.readdir

const testFolder = './tests/';
const fs = require('fs');

fs.readdir(testFolder, (err, files) => {
  files.forEach(file => {
    console.log(file);
  });
});

fs.readdirSync

const testFolder = './tests/';
const fs = require('fs');

fs.readdirSync(testFolder).forEach(file => {
  console.log(file);
});

두 메서드의 차이점은 첫 번째 메서드는 비동기식이므로 읽기 프로세스가 끝날 때 실행될 콜백 함수를 제공해야합니다.

두 번째는 동기식이며 파일 이름 배열을 반환하지만 읽기 프로세스가 끝날 때까지 코드 실행을 중지합니다.


IMO는 이러한 작업을 수행하는 가장 편리한 방법은 glob 도구 를 사용하는 것 입니다. 다음 은 node.js 용 glob 패키지 입니다. 설치

npm install glob

그런 다음 와일드 카드를 사용하여 파일 이름을 일치시킵니다 (패키지 웹 사이트에서 가져온 예)

var glob = require("glob")

// options is optional
glob("**/*.js", options, function (er, files) {
  // files is an array of filenames.
  // If the `nonull` option is set, and nothing
  // was found, then files is ["**/*.js"]
  // er is an error object or null.
})

위의 대답은 디렉토리에 대한 재귀 검색을 수행하지 않습니다. 여기에 내가 재귀 검색에 무슨 짓을했는지 (사용 노드 산책 : npm install walk)

var walk    = require('walk');
var files   = [];

// Walker options
var walker  = walk.walk('./test', { followLinks: false });

walker.on('file', function(root, stat, next) {
    // Add this file to the list of files
    files.push(root + '/' + stat.name);
    next();
});

walker.on('end', function() {
    console.log(files);
});

모든 하위 디렉토리에서 파일 가져 오기

function getFiles (dir, files_){
    files_ = files_ || [];
    var files = fs.readdirSync(dir);
    for (var i in files){
        var name = dir + '/' + files[i];
        if (fs.statSync(name).isDirectory()){
            getFiles(name, files_);
        } else {
            files_.push(name);
        }
    }
    return files_;
}

console.log(getFiles('path/to/dir'))

다음은 기본 fspath모듈 만 사용하는 간단한 솔루션입니다 .

// sync version
function walkSync(currentDirPath, callback) {
    var fs = require('fs'),
        path = require('path');
    fs.readdirSync(currentDirPath).forEach(function (name) {
        var filePath = path.join(currentDirPath, name);
        var stat = fs.statSync(filePath);
        if (stat.isFile()) {
            callback(filePath, stat);
        } else if (stat.isDirectory()) {
            walkSync(filePath, callback);
        }
    });
}

또는 비동기 버전 ( fs.readdir대신 사용) :

// async version with basic error handling
function walk(currentDirPath, callback) {
    var fs = require('fs'),
        path = require('path');
    fs.readdir(currentDirPath, function (err, files) {
        if (err) {
            throw new Error(err);
        }
        files.forEach(function (name) {
            var filePath = path.join(currentDirPath, name);
            var stat = fs.statSync(filePath);
            if (stat.isFile()) {
                callback(filePath, stat);
            } else if (stat.isDirectory()) {
                walk(filePath, callback);
            }
        });
    });
}

그런 다음 (동기화 버전의 경우) 호출하십시오.

walkSync('path/to/root/dir', function(filePath, stat) {
    // do something with "filePath"...
});

또는 비동기 버전 :

walk('path/to/root/dir', function(filePath, stat) {
    // do something with "filePath"...
});

차이점은 IO를 수행하는 동안 노드가 차단되는 방식입니다. 위의 API가 동일하므로 비동기 버전을 사용하여 최대 성능을 보장 할 수 있습니다.

그러나 동기 버전을 사용하면 한 가지 장점이 있습니다. 걷기 후 다음 문에서와 같이 걷기가 완료되는 즉시 일부 코드를 실행하는 것이 더 쉽습니다. 비동기 버전을 사용하면 완료시기를 알 수있는 추가 방법이 필요합니다. 먼저 모든 경로의 맵을 만든 다음 열거 할 수 있습니다. 간단한 빌드 / 유틸 스크립트 (고성능 웹 서버 대)의 경우 손상없이 동기화 버전을 사용할 수 있습니다.


ES7에서 Promise 사용

mz / fs와 비동기식 사용

mz모듈은 핵심 노드 라이브러리의 약속 된 버전을 제공합니다. 그것들을 사용하는 것은 간단합니다. 먼저 라이브러리를 설치하십시오 ...

npm install mz

그때...

const fs = require('mz/fs');
fs.readdir('./myDir').then(listing => console.log(listing))
  .catch(err => console.error(err));

또는 ES7의 비동기 함수로 작성할 수 있습니다.

async function myReaddir () {
  try {
    const file = await fs.readdir('./myDir/');
  }
  catch (err) { console.error( err ) }
};

재귀 목록 업데이트

일부 사용자는 재귀 목록을 보려는 욕구를 지정했습니다 (질문에는 포함되지 않음) ... 사용 fs-promise. 주위에 얇은 포장지 mz입니다.

npm install fs-promise;

그때...

const fs = require('fs-promise');
fs.walk('./myDir').then(
    listing => listing.forEach(file => console.log(file.path))
).catch(err => console.error(err));

종속성.

var fs = require('fs');
var path = require('path');

정의.

// String -> [String]
function fileList(dir) {
  return fs.readdirSync(dir).reduce(function(list, file) {
    var name = path.join(dir, file);
    var isDir = fs.statSync(name).isDirectory();
    return list.concat(isDir ? fileList(name) : [name]);
  }, []);
}

용법.

var DIR = '/usr/local/bin';

// 1. List all files in DIR
fileList(DIR);
// => ['/usr/local/bin/babel', '/usr/local/bin/bower', ...]

// 2. List all file names in DIR
fileList(DIR).map((file) => file.split(path.sep).slice(-1)[0]);
// => ['babel', 'bower', ...]

그주의 사항 fileList너무 낙관적이다. 심각한 경우에는 오류 처리를 추가하십시오.


비 재귀 버전

당신은 그것을 재귀 적으로하고 싶다고 말하지 않기 때문에 나는 당신이 디렉토리의 직접적인 자식 만 필요하다고 가정합니다.

샘플 코드 :

const fs = require('fs');
const path = require('path');

fs.readdirSync('your-directory-path')
  .filter((file) => fs.lstatSync(path.join(folder, file)).isFile());

노드 v10.10.0의, 새로운 사용할 수 있습니다 withFileTypes에 대한 옵션 fs.readdirfs.readdirSync과 함께 dirent.isDirectory()디렉토리에있는 파일 이름을 필터링하는 기능. 다음과 같이 보입니다.

fs.readdirSync('./dirpath', {withFileTypes: true})
.filter(item => !item.isDirectory())
.map(item => item.name)

반환 된 배열은 다음과 같은 형식입니다.

['file1.txt', 'file2.txt', 'file3.txt']

fs.Dirent 클래스 용 문서


부하 fs:

const fs = require('fs');

비동기 파일 읽기 :

fs.readdir('./dir', function (err, files) {
    // "files" is an Array with files names
});

파일 동기화 읽기 :

var files = fs.readdirSync('./dir');

가져 오기 sorted파일 이름을. 당신은 특정에 따라 결과를 필터링 할 수 있습니다 extension와 같은 '.txt', '.jpg'등등.

import * as fs from 'fs';
import * as Path from 'path';

function getFilenames(path, extension) {
    return fs
        .readdirSync(path)
        .filter(
            item =>
                fs.statSync(Path.join(path, item)).isFile() &&
                (extension === undefined || Path.extname(item) === extension)
        )
        .sort();
}

다음은 비동기 재귀 버전입니다.

    function ( path, callback){
     // the callback gets ( err, files) where files is an array of file names
     if( typeof callback !== 'function' ) return
     var
      result = []
      , files = [ path.replace( /\/\s*$/, '' ) ]
     function traverseFiles (){
      if( files.length ) {
       var name = files.shift()
       fs.stat(name, function( err, stats){
        if( err ){
         if( err.errno == 34 ) traverseFiles()
    // in case there's broken symbolic links or a bad path
    // skip file instead of sending error
         else callback(err)
        }
        else if ( stats.isDirectory() ) fs.readdir( name, function( err, files2 ){
         if( err ) callback(err)
         else {
          files = files2
           .map( function( file ){ return name + '/' + file } )
           .concat( files )
          traverseFiles()
         }
        })
        else{
         result.push(name)
         traverseFiles()
        }
       })
      }
      else callback( null, result )
     }
     traverseFiles()
    }

누군가 여전히 이것을 검색한다면, 나는 이것을한다 :

import fs from 'fs';
import path from 'path';

const getAllFiles = dir =>
    fs.readdirSync(dir).reduce((files, file) => {
        const name = path.join(dir, file);
        const isDirectory = fs.statSync(name).isDirectory();
        return isDirectory ? [...files, ...getAllFiles(name)] : [...files, name];
    }, []);

저에게 아주 좋은 일입니다


@ Hunan-Rostomyan의 일반적인 접근 방식을 취하여 좀 더 간결하게 만들고 excludeDirs논쟁을 추가했습니다 . 으로 확장하는 것은 사소한 includeDirs일이며 동일한 패턴을 따르십시오.

import * as fs from 'fs';
import * as path from 'path';

function fileList(dir, excludeDirs?) {
    return fs.readdirSync(dir).reduce(function (list, file) {
        const name = path.join(dir, file);
        if (fs.statSync(name).isDirectory()) {
            if (excludeDirs && excludeDirs.length) {
                excludeDirs = excludeDirs.map(d => path.normalize(d));
                const idx = name.indexOf(path.sep);
                const directory = name.slice(0, idx === -1 ? name.length : idx);
                if (excludeDirs.indexOf(directory) !== -1)
                    return list;
            }
            return list.concat(fileList(name, excludeDirs));
        }
        return list.concat([name]);
    }, []);
}

사용 예 :

console.log(fileList('.', ['node_modules', 'typings', 'bower_components']));

재귀 적으로 할 수도 있습니다.

이를위한 NPM 모듈이 있습니다.

npm dree

이를 통해 디렉토리 트리를 문자열 또는 객체로 표현할 수 있습니다. 파일 콜백을 사용하면 목표에 도달 할 수도 있습니다. 원하는 경우 고려할 파일 확장명을 지정할 수도 있습니다.

다음은 코드입니다.

const dree = require('dree');

const fileNames = [];
const fileCb = function(file) {
    fileNames.push(file.name);
}

dree.scan('path-to-directory', { extensions: [ 'html', 'js' ] }, fileCb);

console.log(fileNames); // All the html and js files inside the given folder and its subfolders

주의 : 디렉토리의 각 파일에 대해 작업을 수행 할 계획이라면 vinyl-fs ( 스트리밍 빌드 시스템 인 gulp 에서 사용됨)를 사용해보십시오 .


이 작업을 자동화하기 위해 노드 모듈을 만들었습니다. mddir

용법

노드 mddir "../relative/path/"

설치하려면 : npm install mddir -g

현재 디렉토리에 대한 마크 다운을 생성하려면 : mddir

절대 경로를 생성하려면 : mddir / absolute / path

상대 경로를 생성하려면 : mddir ~ / Documents / whatever.

md 파일은 작업 디렉토리에 생성됩니다.

현재 node_modules 및 .git 폴더를 무시합니다.

문제 해결

'node \ r : No such file or directory'라는 오류 메시지가 표시되면 운영 체제가 다른 줄 끝을 사용하고 mddir이 명시 적으로 줄 끝 스타일을 Unix로 설정하지 않으면이를 구문 분석 할 수 없다는 문제입니다. 이는 일반적으로 Windows뿐만 아니라 일부 Linux 버전에도 영향을 미칩니다. 줄 끝을 Unix 스타일로 설정하려면 mddir npm global bin 폴더 내에서 수행해야합니다.

줄 끝 수정

다음을 사용하여 npm bin 폴더 경로를 가져옵니다.

npm config get prefix

해당 폴더에 CD

양조 설치 dos2unix

dos2unix lib / node_modules / mddir / src / mddir.js

이것은 줄 끝을 Dos 대신 Unix로 변환합니다.

그런 다음 node mddir "../relative/path/"를 사용하여 정상적으로 실행합니다.

생성 된 마크 다운 파일 구조 'directoryList.md'예제

    |-- .bowerrc
    |-- .jshintrc
    |-- .jshintrc2
    |-- Gruntfile.js
    |-- README.md
    |-- bower.json
    |-- karma.conf.js
    |-- package.json
    |-- app
        |-- app.js
        |-- db.js
        |-- directoryList.md
        |-- index.html
        |-- mddir.js
        |-- routing.js
        |-- server.js
        |-- _api
            |-- api.groups.js
            |-- api.posts.js
            |-- api.users.js
            |-- api.widgets.js
        |-- _components
            |-- directives
                |-- directives.module.js
                |-- vendor
                    |-- directive.draganddrop.js
            |-- helpers
                |-- helpers.module.js
                |-- proprietary
                    |-- factory.actionDispatcher.js
            |-- services
                |-- services.cardTemplates.js
                |-- services.cards.js
                |-- services.groups.js
                |-- services.posts.js
                |-- services.users.js
                |-- services.widgets.js
        |-- _mocks
            |-- mocks.groups.js
            |-- mocks.posts.js
            |-- mocks.users.js
            |-- mocks.widgets.js

npm 목록 내용 모듈을 사용하십시오 . 주어진 디렉토리의 내용과 하위 내용을 읽고 파일과 폴더의 경로 목록을 반환합니다.

const list = require('list-contents');

list("./dist",(o)=>{
  if(o.error) throw o.error;
   console.log('Folders: ', o.dirs);
   console.log('Files: ', o.files);
});

이것은 TypeScript이며 선택적으로 재귀 적이며 선택적으로 오류 로깅 및 비동기 솔루션입니다. 찾으려는 파일 이름에 대한 정규식을 지정할 수 있습니다.

나는 fs-extra그것의 쉬운 슈퍼 세트 개선 때문에 사용 했다 fs.

import * as FsExtra from 'fs-extra'

/**
 * Finds files in the folder that match filePattern, optionally passing back errors .
 * If folderDepth isn't specified, only the first level is searched. Otherwise anything up
 * to Infinity is supported.
 *
 * @static
 * @param {string} folder The folder to start in.
 * @param {string} [filePattern='.*'] A regular expression of the files you want to find.
 * @param {(Error[] | undefined)} [errors=undefined]
 * @param {number} [folderDepth=0]
 * @returns {Promise<string[]>}
 * @memberof FileHelper
 */
public static async findFiles(
    folder: string,
    filePattern: string = '.*',
    errors: Error[] | undefined = undefined,
    folderDepth: number = 0
): Promise<string[]> {
    const results: string[] = []

    // Get all files from the folder
    let items = await FsExtra.readdir(folder).catch(error => {
        if (errors) {
            errors.push(error) // Save errors if we wish (e.g. folder perms issues)
        }

        return results
    })

    // Go through to the required depth and no further
    folderDepth = folderDepth - 1

    // Loop through the results, possibly recurse
    for (const item of items) {
        try {
            const fullPath = Path.join(folder, item)

            if (
                FsExtra.statSync(fullPath).isDirectory() &&
                folderDepth > -1)
            ) {
                // Its a folder, recursively get the child folders' files
                results.push(
                    ...(await FileHelper.findFiles(fullPath, filePattern, errors, folderDepth))
                )
            } else {
                // Filter by the file name pattern, if there is one
                if (filePattern === '.*' || item.search(new RegExp(filePattern, 'i')) > -1) {
                    results.push(fullPath)
                }
            }
        } catch (error) {
            if (errors) {
                errors.push(error) // Save errors if we wish
            }
        }
    }

    return results
}

이것은 작동하고 결과를 동일한 디렉토리에있는 test.txt 파일에 저장합니다.

  fs.readdirSync(__dirname).forEach(file => {
    fs.appendFileSync("test.txt", file+"\n", function(err){
    })
})

function getFilesRecursiveSync(dir, fileList, optionalFilterFunction) {
    if (!fileList) {
        grunt.log.error("Variable 'fileList' is undefined or NULL.");
        return;
    }
    var files = fs.readdirSync(dir);
    for (var i in files) {
        if (!files.hasOwnProperty(i)) continue;
        var name = dir + '/' + files[i];
        if (fs.statSync(name).isDirectory()) {
            getFilesRecursiveSync(name, fileList, optionalFilterFunction);
        } else {
            if (optionalFilterFunction && optionalFilterFunction(name) !== true)
                continue;
            fileList.push(name);
        }
    }
}

참고 URL : https://stackoverflow.com/questions/2727167/how-do-you-get-a-list-of-the-names-of-all-files-present-in-a-directory-in-node -제이

반응형