fs.readdir ignore directories
Asked Answered
E

2

30

I would like to scan the folder, but ignore all the folders/directories that are included in it. All I have in the (C:/folder/) are .txt files and other folders, I just want to scan the txt files, and ignore the folders.

app.get('/generatE', function (req, res) {
  const logsFolder = 'C:/folder/';
  fs.readdir(logsFolder, (err, files) => {
    if (err) {
      res.send("[empty]");
      return;
     }
     var lines = [];
     files.forEach(function(filename) {
       var logFileLines = fs.readFileSync (logsFolder + filename, 'ascii').toString().split("\n");

       logFileLines.forEach(function(logFileLine) {


         if(logFileLine.match(/.*AUDIT*./)) {
           lines.push(logFileLine+'\n');
         }
       })
     })
Echeverria answered 4/1, 2017 at 19:51 Comment(1)
Did you read this answers before? #25461074Halfwitted
V
55

Use fs.readdir or fs.readdirSync method with options { withFileTypes: true } and then do filtration using dirent.isFile (requires Node 10.10+).

Sync version

const fs = require('fs');
const dirents = fs.readdirSync(DIRECTORY_PATH, { withFileTypes: true });
const filesNames = dirents
    .filter(dirent => dirent.isFile())
    .map(dirent => dirent.name);
// use filesNames

Async version (with async/await, requires Node 11+)

import { promises as fs } from 'fs';

async function listFiles(directory) {
    const dirents = await fs.readdir(directory, { withFileTypes: true });
    return dirents
        .filter(dirent => dirent.isFile())
        .map(dirent => dirent.name);
}

Async version (with callbacks)

const fs = require('fs');
fs.readdir(DIRECTORY_PATH, { withFileTypes: true }, (err, dirents) => {
    const filesNames = dirents
        .filter(dirent => dirent.isFile())
        .map(dirent => dirent.name);
    // use filesNames
});
Vigor answered 9/9, 2018 at 10:54 Comment(4)
why is using dirents the proper way? whats wrong with using stats?Commandeer
While the original question was regarding folders and in a windows enviroment I assume the solution is not the most correct one. Unless there some sane reason to not do it this way (please tell).Even if folders might give you problems, but I promise you program will be just as supprised and cranky when it come across /dev/null a socket or something else non file const filesNames = dirents .filter(dirent => dirent.isFile()) .map(dirent => dirent.name);Nonu
Totally agree with @Griffin, I've just run into a situation that the directory contains several symlinks dirent.isSymbolicLink() === true, on macOS, when the source of the symlink is a file, everything works as expected, but once it's a dir, I get an error of Error: EISDIR: illegal operation on a directory, read, I have to filter them out via recursive calls.Psychokinesis
when the source of the symlink is ... a dir ... have to filter them out via recursive calls ---- Actually fs.stat() is more convenient for this use case, which follows symlink automatically.Psychokinesis
I
3

Please See diralik's answer as it is more complete: my answer only works if ALL filenames contain a '.txt' extension.

why not just filter out files that end in ".txt"?

var fs = require("fs")
fs.readdirSync("./").filter(function(file) {
    if(file.indexOf(".txt")>-1)console.log(file)
})

I should have added previously that to get an array of these files you need to return them to an array as shown below.

var fs = require("fs")
let text_file_array = fs.readdirSync("./").filter(function(file) {
    if(file.indexOf(".txt")>-1) return file;
})
Isley answered 4/1, 2017 at 20:7 Comment(5)
or .filter(f => f.includes(".txt")) with ES6Cilo
minus one because not working in generic case (when file extenstion is unknown)Vigor
also another minus one because it will not work for files without extension like DockerFileLangill
I have amended my answer with a warning of the possible side-effects.Isley
Also does not work when a directory name ends with .txt.Contraindicate

© 2022 - 2024 — McMap. All rights reserved.