在nodejs中读取多个文件同时根据文件内容生成一个对象的问题?

有了钱再署名
  • 19

有2个文件txt.txt,txt2.txt
内容如下:
txt.txt-> OG0000000: AT1G01250 AT1G04370 AT1G06160 AT1G12630
txt2.txt-> OG0000001: AT1G01251 AT1G04371 AT1G06161 AT1G12631

想处理后的结果如下

{
    AT1G01250:OG0000000,
    AT1G04370:OG0000000,
    AT1G06160:OG0000000,
    AT1G12630:OG0000000,
    AT1G01251:OG0000001,
    AT1G04371:OG0000001,
    AT1G06161:OG0000001,
    AT1G12631:OG0000001,
}

简而言之就是会将:后的数据做key,前面做value生成一个对象

private async initProteinObject(TXTFilesPath: string): Promise<any> {
    const proteinObject: IProteinObject = {};
    try {
      fs.readdir(TXTFilesPath, async (err, files: string[]) => {
        if (err) {
          console.error(err);
          return;
        }
        const promises = await files.map(file => {
          new Promise((resolve, reject) => {
            const filrdir: string = path.join(TXTFilesPath, file);
            if (path.extname(filrdir) === 'txt') {
              fs.stat(filrdir, async (err, stats) => {
                if (err) {
                  console.error(err);
                  return;
                }
                if (stats.isFile()) {
                  const rl = readline.createInterface(
                    fs.createReadStream(filrdir),
                  );
                  for await (const line of rl) {
                    const fastaName = line.split(':')[0];
                    const idList = line.split(':')[1];
                    let temList = [];
                    temList = [...new Set(idList.trim().split(' '))];
                    for (let i = 0; i < temList.length; i++) {
                      const ele = temList[i];
                      proteinObject[ele] = fastaName;
                    }
                  }
                  console.log('proteinObject', proteinObject);
                  resolve(proteinObject);
                }
              });
            } else {
              resolve({});
            }
          });
        });
        return Promise.all(promises).then(arr => console.log(arr));
      });
    } catch (error) {
      throw new Error(error);
    }
  }

这个代码并不能得出正确的结果,请问应该怎么改。想有一个工具函数来批处理这些文件返回一个对象。

回复
阅读 3.1k
4 个回答
const obj = {};
const files = [
    'OG0000000: AT1G01250 AT1G04370 AT1G06160 AT1G12630', 
    'OG0000001: AT1G01251 AT1G04371 AT1G06161 AT1G12631' 
];

files.forEach(e => {
    const arr = e.split(':');
    arr[1].trim().split(' ').forEach(k => {
        obj[k] = arr[0];
    });
});

console.log(obj);

image.png

至于你怎么读取文件内容到 files 数组里面,这不用教吧?

node读取文件也可以通过同步的方式呀
同步读取文件:fs.readFileSync
同步读取文件夹:fs.readdirSync
你可以搜搜这两个的用法,获取对你有帮助

改好了,现在是这样,问题不会关闭,感觉代码健壮性不够,欢迎赐教

private async initProteinObject(TXTFilesPath: string): Promise<any> {
    return new Promise((resolve, reject) => {
      fs.readdir(TXTFilesPath, async (err, files: string[]) => {
        if (err) {
          console.error(err);
          return;
        }
        const promises = files.map(file => {
          return new Promise((resolve, reject) => {
            const filrdir: string = path.join(TXTFilesPath, file);
            if (path.extname(filrdir) === '.txt') {
              fs.stat(filrdir, async (err, stats) => {
                if (err) {
                  console.error(err);
                  return;
                }
                if (stats.isFile()) {
                  const rl = readline.createInterface(
                    fs.createReadStream(filrdir),
                  );
                  const proteinObject: IProteinObject = {};
                  for await (const line of rl) {
                    const fastaName = line.split(':')[0];
                    const idList = line.split(':')[1];
                    let temList = [];
                    temList = [...new Set(idList.trim().split(' '))];
                    for (let i = 0; i < temList.length; i++) {
                      const ele = temList[i];
                      proteinObject[ele] = fastaName;
                    }
                  }
                  resolve(proteinObject);
                }
              });
            } else {
              resolve({});
            }
          });
        });
        let res = {};
        Promise.all(promises).then(arr => {
          arr.forEach(item => Object.assign(res, item));
          resolve(res);
        });
      });
    });
  }

看看这样满足不。

var fs = require('fs');
var path = require('path');
// 路径是我本地,模拟test文件夹下两个txt文件
var filePath = path.resolve('./test');

var result = {}
fileDisplay(filePath);
//文件遍历
function fileDisplay(filePath){
    fs.readdir(filePath,function(err,files){
        if(err){
            console.warn(err)
        }else{
            //遍历文件列表
            files.forEach(function(filename){
                var filedir = path.join(filePath, filename);
                fs.stat(filedir,function(eror, stats){
                    if(eror){
                        console.warn('获取文件stats失败');
                    }else{
                        var isFile = stats.isFile();
                        var isDir = stats.isDirectory();
                        if(isFile){
                            console.log(filedir);
                 // 读取文件内容
                            var content = fs.readFileSync(filedir, 'utf-8');
                            console.log(content);
                            var contentArr = content.split(':')
                            var value = contentArr[0].trim()
                            var name = contentArr[1].trim()
                            var nameArr = name.split(' ')
                            for (var i = 0; i < nameArr.length; i++) {
                              result[nameArr[i]] = value
                            }
                            console.log(result)
                        }
                        if(isDir){
                            // 递归
                            fileDisplay(filedir);
                        }
                    }
                })
            });
        }
    });
}
宣传栏