Дир ходьба, чтобы получить абс путь массив различных файлов - PullRequest
0 голосов
/ 20 сентября 2018

Цель: получить список абсолютных путей для всех файлов в каталоге, рекурсивно использующих NodeJ.

Информация: Как разработчик Python, я обычно использую пакеты Python, которые обрабатывают это независимо от платформы.Моему боссу нужен был некоторый код javascript, который бы справился с этой задачей ... и, как ранее разработчик JS, я сказал: "О, это просто. Давайте посмотрим на узел, так как у меня никогда не было шанса испачкать его руками".но я, кажется, ошибаюсь.

Я не вижу ничего в узле, касающемся Dir Walking, или способа, которым я мог бы взломать вместе, чтобы создать такую ​​вещь.

Я искал в "Дочерний процесс »,« Консоль »,« Файловая система »,« ОС »,« Путь »и« Процесс ».Я не видел ничего, что могло бы сделать что-то похожее на:

pushd .
cd $dir
for folder in $(ls);
do
  pushd .
  cd $folder
    //call again
  ls $(pwd)$flag >> $dir/files_matching.txt 
  popd
done;

 // or any platform independent means of recursively getting 
 // all files and their abs path which meet flag criterion, 
 //  such as "*.txt" || "_*found*"

Я мог бы использовать дочерний процесс для выполнения элементов командной строки, но затем мне нужно создать набор условий на основе ОС, потребляющейapp, и решил, что это будет нечто, что уже существует.

Я не хочу изобретать велосипед, но решил, что это уже сделано;Я просто не вижу его в базовых модулях.

Нужен ли мне узел-модуль, который бы выполнял эту задачу, который находится за пределами базовых модулей?

Я стараюсь не иметьвручную обработать систему на основе условной ОС, чтобы получить исчерпывающий список путей abs для всех файлов в каталоге (или подмножестве из-за расширений и т. д.)

Ответы [ 2 ]

0 голосов
/ 21 сентября 2018

Я бы сделал это так:

синхронно:

const fs = require("fs");
const { resolve } = require("path");

const getFiles = dir => {
  const stack = [resolve(dir)];
  const files = [];
  while (stack.length) {
    dir = stack.pop();
    fs.readdirSync(dir).forEach(item => {
      const path = resolve(dir, item);
      (fs.statSync(path).isDirectory() ? stack : files).push(path);
    });
  }
  return files;
};

console.log(getFiles("."));

асинхронно:

const fs = require("fs");
const { resolve } = require("path");
const pify = require("util").promisify;
const readdir = pify(fs.readdir);
const stat = pify(fs.stat);

const getFiles = async dir => {
  const files = await readdir(resolve(dir));
  const filesP = files.map(async file => {
    const path = resolve(dir, file);
    return (await stat(path)).isDirectory() ? getFiles(path) : path;
  });
  // return (await Promise.all(filesP)).flat(); // flat supported in node ~11
  return [].concat(...(await Promise.all(filesP)));
};

getFiles(".").then(console.log);

асинхронная демонстрация https://repl.it/@marzelin/getFiles

0 голосов
/ 20 сентября 2018

Итак, я посмотрел на модуль файловой системы и заметил функцию readDir

https://nodejs.org/dist/latest-v8.x/docs/api/fs.html#fs_fs_readdir_path_options_callback

, которая частично справляется с задачей.Я думаю, это не был назван метод, который я искал бы.Я искал вещи, включающие LIST и DIR, но не READ.

В любом случае, вот способ прочитать Dir.

var fs = require('fs');

if (process.argv.length <= 2) {
    console.log("Usage: " + __filename + " path/to/directory");
    process.exit(-1);
}

var path = process.argv[2];

fs.readdir(path, function(err, items) {
    console.log(items);

    for (var i=0; i<items.length; i++) {
        console.log(items[i]);
    }
});

Вы заметили, что это выше Async, но тамвариант синхронизации, просто добавьте "Синхронизация" к подписи.Теперь вам нужно определить, является ли что-то каталогом:

let file = fs.statSync("path/to/directory")
let isDir = file.isDirectory()

Так что вы можете соединить все это вместе.

var fs = require('fs')
function recurse_file_system(path, contains) {
  let files = fs.readdirSync(path);
  let dArr = [];
  let fArr = [];
  for (let i in files){
    let newPath = path + "/" + files[i]
    if (fs.statSync(newPath).isDirectory()){
      dArr.push(newPath)
    }else{
      if (filter(files[i], ".txt")){
         fArr.push(newPath)
      }
    }
  }
  if (arr.length == 0){
    return fArr;
  }else{
    for (let d in dArr){
      let rslt = recurse_file_system(dArr[d]);
      for (let i in rslt){
        fArr.push(rslt[i])
      }
    }
    return fArr;
  }
}
console.log("Files:")
console.log(recurse_file_system("/"))

Теперь, если вы хотите расширить это, все, что вам нужно сделатьэто добавить фильтр, чтобы сказать, ограничить размер возвращаемых данных на основе определенного критерия, такого как ограничение имени файла.

function filter(filename, contains){
   let reg = new RegEx(contains)
   return reg.test(filename)
}

, и вы можете добавить его в базовый вариант, где вы видите фильтр ... ИЛИВы можете просто вернуть ВЕСЬ набор и отфильтровать его там с помощью метода List, filter.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...