【问题标题】:fs.readdir ignore directoriesfs.readdir 忽略目录
【发布时间】:2017-01-04 19:51:56
【问题描述】:

我想扫描文件夹,但忽略其中包含的所有文件夹/目录。我在 (C:/folder/) 中只有 .txt 文件和其他文件夹,我只想扫描 txt 文件,而忽略这些文件夹。

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');
         }
       })
     })

【问题讨论】:

标签: javascript node.js readdir


【解决方案1】:

使用fs.readdirfs.readdirSync 方法和{ withFileTypes: true } 选项,然后使用dirent.isFile 进行过滤(需要节点10.10+)。

同步版本

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/await,需要节点 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);
}

异步版本(带回调)

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
});

【讨论】:

  • 为什么正确使用dirents?使用统计数据有什么问题?
  • 虽然最初的问题是关于文件夹和在 Windows 环境中,但我认为解决方案不是最正确的。除非有一些理智的理由不这样做(请告诉)。即使文件夹可能会给您带来问题,但我保证您的程序在遇到 /dev/null 套接字或其他非文件常量 filesNames = dirents .filter(dirent => dirent.isFile()) .map(dirent => dirent.name);
  • 完全同意@Griffin,我刚刚遇到了这样一种情况,即目录包含多个符号链接dirent.isSymbolicLink() === true,在macOS上,当符号链接的源是一个文件时,一切都按预期工作,但是一旦它是一个目录,我就会收到Error: EISDIR: illegal operation on a directory, read 的错误,我必须通过递归调用将它们过滤掉。
  • when the source of the symlink is ... a dir ... have to filter them out via recursive calls ---- 实际上fs.stat() 更适合这个用例,它会自动跟随符号链接。
【解决方案2】:

请参阅 diralik 的回答,因为它更完整:我的回答仅适用于所有文件名包含“.txt”扩展名的情况。

为什么不过滤掉以“.txt”结尾的文件呢?

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

我之前应该添加,要获取这些文件的数组,您需要将它们返回到数组中,如下所示。

var fs = require("fs")
let text_file_array = fs.readdirSync("./").filter(function(file) {
    if(file.indexOf(".txt")>-1) return file;
})

【讨论】:

  • .filter(f => f.includes(".txt")) ES6
  • 减一,因为不能在一般情况下工作(当文件扩展名未知时)
  • 还有一个减号,因为它不适用于像 DockerFile 这样没有扩展名的文件
  • 我已经修改了我的答案,警告可能的副作用。
  • 目录名以.txt结尾时也不起作用。
猜你喜欢
  • 1970-01-01
  • 2017-06-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多