best way to get folder and file list in Javascript

前端 未结 4 595
太阳男子
太阳男子 2020-12-05 14:03

I\'m using node-webkit, and am trying to have a user select a folder, and I\'ll return the directory structure of that folder and recursively get its children.

I\'v

相关标签:
4条回答
  • 2020-12-05 14:27

    fs/promises and fs.Dirent

    Here's an efficient, non-blocking ls program using Node's fast fs.Dirent objects and fs/promises module. This approach allows you to skip wasteful fs.exist or fs.stat calls on every path -

    // main.js
    import { readdir } from "fs/promises"
    import { join } from "path"
    
    async function* ls (path = ".")
    { yield path
      for (const dirent of await readdir(path, { withFileTypes: true }))
        if (dirent.isDirectory())
          yield* ls(join(path, dirent.name))
        else
          yield join(path, dirent.name)
    }
    
    async function* empty () {}
    
    async function toArray (iter = empty())
    { let r = []
      for await (const x of iter)
        r.push(x)
      return r
    }
    
    toArray(ls(".")).then(console.log, console.error)
    

    Let's get some sample files so we can see ls working -

    $ yarn add immutable     # (just some example package)
    $ node main.js
    
    [
      '.',
      'main.js',
      'node_modules',
      'node_modules/.yarn-integrity',
      'node_modules/immutable',
      'node_modules/immutable/LICENSE',
      'node_modules/immutable/README.md',
      'node_modules/immutable/contrib',
      'node_modules/immutable/contrib/cursor',
      'node_modules/immutable/contrib/cursor/README.md',
      'node_modules/immutable/contrib/cursor/__tests__',
      'node_modules/immutable/contrib/cursor/__tests__/Cursor.ts.skip',
      'node_modules/immutable/contrib/cursor/index.d.ts',
      'node_modules/immutable/contrib/cursor/index.js',
      'node_modules/immutable/dist',
      'node_modules/immutable/dist/immutable-nonambient.d.ts',
      'node_modules/immutable/dist/immutable.d.ts',
      'node_modules/immutable/dist/immutable.es.js',
      'node_modules/immutable/dist/immutable.js',
      'node_modules/immutable/dist/immutable.js.flow',
      'node_modules/immutable/dist/immutable.min.js',
      'node_modules/immutable/package.json',
      'package.json',
      'yarn.lock'
    ]
    

    For added explanation and other ways to leverage async generators, see this Q&A.

    0 讨论(0)
  • 2020-12-05 14:32

    Why to invent the wheel?

    There is a very popular NPM package, that let you do things like that easy.

    var recursive = require("recursive-readdir");
    
    recursive("some/path", function (err, files) {
      // `files` is an array of file paths
      console.log(files);
    });
    

    Lear more:

    • https://www.npmjs.com/package/recursive-readdir
    0 讨论(0)
  • 2020-12-05 14:32

    I don't like adding new package into my project just to handle this simple task.

    And also, I try my best to avoid RECURSIVE algorithm.... since, for most cases it is slower compared to non Recursive one.

    So I made a function to get all the folder content (and its sub folder).... NON-Recursively

    var getDirectoryContent = function(dirPath) {
        /* 
            get list of files and directories from given dirPath and all it's sub directories
            NON RECURSIVE ALGORITHM
            By. Dreamsavior
        */
        var RESULT = {'files':[], 'dirs':[]};
    
        var fs = fs||require('fs');
        if (Boolean(dirPath) == false) {
            return RESULT;
        }
        if (fs.existsSync(dirPath) == false) {
            console.warn("Path does not exist : ", dirPath);
            return RESULT;
        }
    
        var directoryList = []
        var DIRECTORY_SEPARATOR = "\\";
        if (dirPath[dirPath.length -1] !== DIRECTORY_SEPARATOR) dirPath = dirPath+DIRECTORY_SEPARATOR;
    
        directoryList.push(dirPath); // initial
    
        while (directoryList.length > 0) {
            var thisDir  = directoryList.shift(); 
            if (Boolean(fs.existsSync(thisDir) && fs.lstatSync(thisDir).isDirectory()) == false) continue;
    
            var thisDirContent = fs.readdirSync(thisDir);
            while (thisDirContent.length > 0) { 
                var thisFile  = thisDirContent.shift(); 
                var objPath = thisDir+thisFile
    
                if (fs.existsSync(objPath) == false) continue;
                if (fs.lstatSync(objPath).isDirectory()) { // is a directory
                    let thisDirPath = objPath+DIRECTORY_SEPARATOR; 
                    directoryList.push(thisDirPath);
                    RESULT['dirs'].push(thisDirPath);
    
                } else  { // is a file
                    RESULT['files'].push(objPath); 
    
                } 
            } 
    
        }
        return RESULT;
    }
    

    the only drawback of this function is that this is Synchronous function... You have been warned ;)

    0 讨论(0)
  • 2020-12-05 14:35

    In my project I use this function for getting huge amount of files. It's pretty fast (put require("FS") out to make it even faster):

    var _getAllFilesFromFolder = function(dir) {
    
        var filesystem = require("fs");
        var results = [];
    
        filesystem.readdirSync(dir).forEach(function(file) {
    
            file = dir+'/'+file;
            var stat = filesystem.statSync(file);
    
            if (stat && stat.isDirectory()) {
                results = results.concat(_getAllFilesFromFolder(file))
            } else results.push(file);
    
        });
    
        return results;
    
    };
    

    usage is clear:

    _getAllFilesFromFolder(__dirname + "folder");
    
    0 讨论(0)
提交回复
热议问题