使用fs.readdir和fs.stat列出目录中的文件并推送到数组

问题描述

我正尝试在fs.readdir和fs.stat(NodeJS版本9.8.0)的帮助下获取目录中的文件列表,并将该列表推入JSON数组,但未填充。我可以使用同步方法like this)来完成此操作,但我想使用异步方法来完成此操作。 进行了一些谷歌搜索之后才知道,这与回调有关。到回调完成时,响应已经发送出去(如果这种理解是错误的,请更正)。 以下是编写的原始代码

var dirToRead = "allfiles";
app.get('/getDownloadFilesList',(req,res)=>{
 var allFilesInfo = [];
 fs.readdir(dirToRead,(err,files)=>{
  var allFilesInfo = [];
    files.forEach(function(file,index){
      fs.stat(dirToRead+"/"+file,stats)=>{
        (err) => {return console.err(err)}
        allFilesInfo.push({"Count":index,"fileName":file,"fileSize":stats.size});
      });
    });
  });
});

然后我尝试将promisify与NodeJS的util包一起使用,但是没有运气。有人可以帮忙吗?

const myUtil = require('util')
var dirToRead = "allfiles";
app.get('/getDownloadFilesList',res)=>{
  var allFilesInfo = [];
  const readdir = myUtil.promisify(fs.readdir);
  const stat = myUtil.promisify(fs.stat);
  readdir(dirToRead).then((files)=>{
    files.forEach(function(file,index){
      stat(dirToRead+"/"+file).then(function(stats){
        allFilesInfo.push({"Count":index,"fileSize":stats.size});
      }).catch((err)=>{
        (err) => {return console.err(err)}
      });
    });
  }).catch((err)=>{
    (err) => {return console.err(err)}
  });
  console.log(allFilesInfo);
  res.send(allFilesInfo);
});

解决方法

您没有等待回调中的循环,因此res.send发生在stat中的任何一个完成之前。最简单的方法是使用Promise.all()

const readdir = myUtil.promisify(fs.readdir);
const stat = myUtil.promisify(fs.stat);

app.get("/getDownloadFilesList",(req,res)=>{
  readdir(dirToRead).then(files => {
    Promise.all(files.map(x => stat(`${dirToRead}/${file}`)))
      .then(stats => stats.map((s,i) => {
           if (s.isFile()) return {"Count":i,"fileName":files[i],"fileSize":s.size});
           else return null;
        })
        .filter(x=> x!= null)
      ) 
      .then(fileInfos => res.send(fileInfos))
      .catch(e => res.sendStatus(400));
  });
});

顺便说一句,NodeJS 9已经过时了,您可能应该升级到较新的版本,该版本还具有一个支持诺言的fs模块。