node.js 生成目录树文件

本文涉及的产品
云解析DNS-重点域名监控,免费拨测 20万次(价值200元)
简介: 我们在很多地方都可以看到有这样的目录树结构,目录树可以很好的介绍项目中各文件目录的用途,帮助读者了解整个项目结构。

说在前面

我们在很多地方都可以看到有这样的目录树结构,目录树可以很好的介绍项目中各文件目录的用途,帮助读者了解整个项目结构。
image.png
由于自己在项目中需要用到这个目录树来进行项目结构介绍,但是在网上简单的找了一下,没找到自己想要的工具,于是就自己动手用node撸了一个,输出效果如上图↑↑↑。

代码实现

依赖模块

需要使用fs和path模块。

const fs = require("fs");
const path = require("path");

参数配置

执行node命令的时候可以携带参数,具体参数如下:
执行node getFileTree.js -h 或 node getFileTree.js -help 控制台会打印提示信息。
node getFileTree.js [参数1] [参数2] [参数3] [参数4] [参数5]
具体代码如下:

let basepath = "../"; //解析目录路径
let filterFile = ["node_modules", "\\..*"]; //过滤文件名,使用,隔开
let stopFloor = 10; //遍历层数
let generatePath = "./fileTree.txt"; //生成文件路径
let isFullPath = true; //是否输出完整路径

//获取入参
let args = process.argv.slice(2);
if (args[0] && (args[0] === "-h" || args[0] === "-help")) {
  console.log("node getFileTree.js [参数1] [参数2] [参数3] [参数4] [参数5]");
  console.log("参数说明");
  console.log("参数1:解析目录路径,默认为'../'");
  console.log(
    "参数2:过滤文件名,使用','隔开,支持正则表达式,默认为'node_modules', '\\..*'"
  );
  console.log("参数3:遍历文件最大层数,默认为10");
  console.log("参数4:生成文件路径,默认为'./fileTree.txt'");
  console.log("参数5:是否输出完整路径,默认为true");
  console.log("参数按顺序读取,不能省略,使用默认值需要输入' '占位,如下:");
  console.log("node getFileTree.js [参数1] ' ' [参数3] [参数4] [参数5]");
  process.exit();
}

if (args[0] && args[0] !== " ") {
  basepath = args[0]; //解析目录路径
}
if (args[1] && args[1] !== " ") {
  filterFile = args[1].split(","); //过滤文件名,使用,隔开
}
if (args[2] && args[2] !== " ") {
  stopFloor = args[2]; //遍历层数
}
if (args[3] && args[3] !== " ") {
  generatePath = args[3]; //生成文件路径
}
if (args[4] && args[4] === "f") {
  isFullPath = false; //是否输出完整路径
}

目录输出以目标文件夹为起始路径

比如我们需要生产目录树的文件夹路径为'../test',我们并不希望输出目录树每一个目录都会带上'../test'这一部分路径,所以应该将这一部分的路径删除。

function getPartPath(dirPath) {
  let base = basepath.split(/\/|\\/g);
  dirPath = dirPath.split(/\/|\\/g);
  while (base.length && dirPath.length && base[0] === dirPath[0]) {
    base.shift();
    dirPath.shift();
  }
  return dirPath.join("/");
}

过滤不想输出的目录文件

我们在打印目录树的时候也希望有些目录文件不被打印出来,如node_modules目录点开头的文件,程序默认的过滤规则为:let filterFile = ["node_modules", "\\..*"];

function isFilterPath(item) {
  for (let i = 0; i < filterFile.length; i++) {
    let reg = filterFile[i];
    if (item.match(reg) && item.match(reg)[0] === item) return true;
  }
  return false;
}

获取文件目录树

使用fs模块中的readdirSync获取目录下的文件目录列表;
使用fs模块中的statSync获取文件信息,isFile方法可以判断是文件还是目录。
是文件则将文件放进列表,是目录则需递归处理目录,最后输出目录树的json数据,具体代码如下:

function processDir(dirPath, dirTree = [], floor = 1) {
  if (floor > stopFloor) return;
  let list = fs.readdirSync(dirPath);
  list = list.filter((item) => {
    return !isFilterPath(item);
  });
  list.forEach((itemPath) => {
    const fullPath = path.join(dirPath, itemPath);
    const fileStat = fs.statSync(fullPath);
    const isFile = fileStat.isFile();
    const dir = {
      name: isFullPath ? getPartPath(fullPath) : itemPath,
    };
    if (!isFile) {
      dir.children = processDir(fullPath, [], floor + 1);
    }
    dirTree.push(dir);
  });
  return dirTree;
}

打印目录树

拼接目录树字符串。

function consoleTree(tree, floor = 1, str = "", adder = "───", isLast = false) {
  str += adder;
  for (let i = 0; i < tree.length; i++) {
    if (floor === 1 && i === 0) {
      fileTree += "\n" + "┌" + str + tree[i].name;
    } else if (
      (isLast || floor === 1) &&
      i === tree.length - 1 &&
      !tree[i].children
    ) {
      fileTree += "\n" + "└" + str + tree[i].name;
    } else {
      fileTree += "\n" + "├" + str + tree[i].name;
    }
    if (tree[i].children)
      consoleTree(
        tree[i].children,
        floor + 1,
        str,
        adder,
        (isLast || floor === 1) && i === tree.length - 1
      );
  }
}

目录树输出到文件中

先清空再写入。

function writeTree(filePath, content) {
  clearTxt(generatePath);
  fs.writeFileSync(filePath, `${content}`);
  console.log(content);
}

清空文件数据

function clearTxt(filePath) {
  fileTree = "";
  fs.writeFileSync(filePath, "");
}

完整代码

/*
 * @Author: zheng yong tao
 * @Date: 2022-03-16 21:27:07
 * @LastEditors: zheng yong tao
 * @LastEditTime: 2022-03-16 23:15:17
 * @Description:
 */

const fs = require("fs");
const path = require("path");

let basepath = "../"; //解析目录路径
let filterFile = ["node_modules", "\\..*"]; //过滤文件名,使用,隔开
let stopFloor = 10; //遍历层数
let generatePath = "./fileTree.txt"; //生成文件路径
let isFullPath = true; //是否输出完整路径

//获取入参
let args = process.argv.slice(2);
if (args[0] && (args[0] === "-h" || args[0] === "-help")) {
  console.log("node getFileTree.js [参数1] [参数2] [参数3] [参数4] [参数5]");
  console.log("参数说明");
  console.log("参数1:解析目录路径,默认为'../'");
  console.log(
    "参数2:过滤文件名,使用','隔开,支持正则表达式,默认为'node_modules', '\\..*'"
  );
  console.log("参数3:遍历文件最大层数,默认为10");
  console.log("参数4:生成文件路径,默认为'./fileTree.txt'");
  console.log("参数5:是否输出完整路径,默认为true");
  console.log("参数按顺序读取,不能省略,使用默认值需要输入' '占位,如下:");
  console.log("node getFileTree.js [参数1] ' ' [参数3] [参数4] [参数5]");
  process.exit();
}

if (args[0] && args[0] !== " ") {
  basepath = args[0]; //解析目录路径
}
if (args[1] && args[1] !== " ") {
  filterFile = args[1].split(","); //过滤文件名,使用,隔开
}
if (args[2] && args[2] !== " ") {
  stopFloor = args[2]; //遍历层数
}
if (args[3] && args[3] !== " ") {
  generatePath = args[3]; //生成文件路径
}
if (args[4] && args[4] === "f") {
  isFullPath = false; //是否输出完整路径
}


function getPartPath(dirPath) {
  let base = basepath.split(/\/|\\/g);
  dirPath = dirPath.split(/\/|\\/g);
  while (base.length && dirPath.length && base[0] === dirPath[0]) {
    base.shift();
    dirPath.shift();
  }
  return dirPath.join("/");
}

function isFilterPath(item) {
  for (let i = 0; i < filterFile.length; i++) {
    let reg = filterFile[i];
    if (item.match(reg) && item.match(reg)[0] === item) return true;
  }
  return false;
}

function processDir(dirPath, dirTree = [], floor = 1) {
  if (floor > stopFloor) return;
  let list = fs.readdirSync(dirPath);
  list = list.filter((item) => {
    return !isFilterPath(item);
  });
  list.forEach((itemPath) => {
    const fullPath = path.join(dirPath, itemPath);
    const fileStat = fs.statSync(fullPath);
    const isFile = fileStat.isFile();
    const dir = {
      name: isFullPath ? getPartPath(fullPath) : itemPath,
    };
    if (!isFile) {
      dir.children = processDir(fullPath, [], floor + 1);
    }
    dirTree.push(dir);
  });
  return dirTree;
}

console.log("获取中,请稍后……");
let dirTree = [];
dirTree = processDir(basepath, dirTree);
let fileTree = '';

function consoleTree(tree, floor = 1, str = "", adder = "───", isLast = false) {
  str += adder;
  for (let i = 0; i < tree.length; i++) {
    if (floor === 1 && i === 0) {
      fileTree += "\n" + "┌" + str + tree[i].name;
    } else if (
      (isLast || floor === 1) &&
      i === tree.length - 1 &&
      !tree[i].children
    ) {
      fileTree += "\n" + "└" + str + tree[i].name;
    } else {
      fileTree += "\n" + "├" + str + tree[i].name;
    }
    if (tree[i].children)
      consoleTree(
        tree[i].children,
        floor + 1,
        str,
        adder,
        (isLast || floor === 1) && i === tree.length - 1
      );
  }
}
console.log("生成中,请稍后……");
function writeTree(filePath, content) {
  clearTxt(generatePath);
  fs.writeFileSync(filePath, `${content}`);
  console.log(content);
}
function clearTxt(filePath) {
  fileTree = "";
  fs.writeFileSync(filePath, "");
}
consoleTree(dirTree);
writeTree(generatePath,fileTree);
console.log("生成结束");

代码地址

Gitee:https://gitee.com/zheng_yongtao/node-scripting-tool.git

image.png

目录
相关文章
|
JavaScript API
深入探索fs.WriteStream:Node.js文件写入流的全面解析
深入探索fs.WriteStream:Node.js文件写入流的全面解析
|
4月前
|
编解码 JavaScript 前端开发
如何在网页播放英文的m3u8文件(基于Javascript搭建的在线网页工具)
什么是m3u8?又该如何在网页中高效、便捷地播放英文的m3u8文件呢?今天这篇文章就带你一起了解,并推荐一种基于Javascript搭建的在线网页工具,让你轻松解决播放问题。
902 0
|
JavaScript 前端开发 内存技术
js文件的入口代码及需要入口代码的原因
js文件的入口代码及需要入口代码的原因
185 0
|
10月前
|
SQL JavaScript 安全
【04】Java+若依+vue.js技术栈实现钱包积分管理系统项目-若依框架二次开发准备工作-以及建立初步后端目录菜单列-优雅草卓伊凡商业项目实战
【04】Java+若依+vue.js技术栈实现钱包积分管理系统项目-若依框架二次开发准备工作-以及建立初步后端目录菜单列-优雅草卓伊凡商业项目实战
436 11
【04】Java+若依+vue.js技术栈实现钱包积分管理系统项目-若依框架二次开发准备工作-以及建立初步后端目录菜单列-优雅草卓伊凡商业项目实战
|
11月前
|
前端开发 JavaScript
【02】v1.0.1更新增加倒计时完成后的放烟花页面-优化播放器-优化结构目录-蛇年新年快乐倒计时领取礼物放烟花html代码优雅草科技央千澈写采用html5+div+CSS+JavaScript-优雅草卓伊凡-做一条关于新年的代码分享给你们-为了C站的分拼一下子
【02】v1.0.1更新增加倒计时完成后的放烟花页面-优化播放器-优化结构目录-蛇年新年快乐倒计时领取礼物放烟花html代码优雅草科技央千澈写采用html5+div+CSS+JavaScript-优雅草卓伊凡-做一条关于新年的代码分享给你们-为了C站的分拼一下子
317 14
【02】v1.0.1更新增加倒计时完成后的放烟花页面-优化播放器-优化结构目录-蛇年新年快乐倒计时领取礼物放烟花html代码优雅草科技央千澈写采用html5+div+CSS+JavaScript-优雅草卓伊凡-做一条关于新年的代码分享给你们-为了C站的分拼一下子
|
JavaScript 前端开发 API
Next.js 实战 (六):如何实现文件本地上传
这篇文章介绍了在Next.js中如何实现文件上传到本地的方法。文章首先提到Next.js官方文档中没有提供文件上传的实例代码,因此开发者需要自行实现,通常有两种思路:使用Node.js原生上传或使用第三方插件如multer。接着,文章选择了使用Node.js原生上传的方式来讲解实现过程,包括如何通过哈希值命名文件、上传到指定目录以及如何分类文件夹。然后,文章展示了具体的实现步骤,包括编写代码来处理文件上传,并给出了代码示例。最后,文章通过一个效果演示说明了如何通过postman模拟上传文件,并展示了上传后的文件夹结构。
363 0
Next.js 实战 (六):如何实现文件本地上传
|
前端开发 JavaScript API
前端JS读取文件内容并展示到页面上
前端JavaScript使用FileReader API读取文件内容,支持文本类型文件。在文件读取成功后,可以通过onload事件处理函数获取文件内容,然后展示到页面上。
476 2
前端JS读取文件内容并展示到页面上
|
JavaScript 前端开发 数据安全/隐私保护
混淆指定js文件
【9月更文挑战第26天】JavaScript 混淆旨在保护代码知识产权、减小文件体积和提高安全性。方法包括变量名和函数名混淆、代码压缩、控制流平坦化及字符串加密。常用工具如 UglifyJS 和 JScrambler 可实现这些功能。然而,混淆可能带来兼容性和调试困难等问题,需谨慎使用并确保法律合规。
221 5
|
移动开发 JavaScript 前端开发
js之操作文件| 12-5
js之操作文件| 12-5
|
存储 JSON JavaScript
学习node.js十三,文件的上传于下载
学习node.js十三,文件的上传于下载