如何使用Node.js遍歷文件夾詳解
前言
最近在寫一個(gè)管理 markdown 文件的工具 knowledge-center,需要讀取指定文件夾內(nèi)所有 markdown 文件。因此需要用 Node.js 來實(shí)現(xiàn)遍歷一個(gè)文件夾內(nèi)所有文件的功能。
Node.js 中提供了這些有用的 API:
- fs.readdir:異步讀取文件夾
- fs.readdirSync:同步讀取文件夾
- fs.statSync:同步獲取文件屬性
獲取的文件列表為數(shù)組格式
對(duì)于遍歷的結(jié)果,我們可以選擇按列表或文件樹來展示。先從最簡單的情況看起,用同步方式處理,返回結(jié)果是一個(gè)列表。
先使用 fs.readdirSync 獲取文件列表,然后遍歷文件列表,使用 fs.statSync 獲取列表中文件的狀態(tài),如果是文件,則添加到文件列表中,如果是文件夾,則遞歸調(diào)用 traverseFolderList 函數(shù),直到獲取到所有文件。
獲取的文件列表為對(duì)象格式
如果我們想展示文件夾目錄結(jié)構(gòu),那么列表格式的就不太方便了。假設(shè)有如下的文件夾結(jié)構(gòu):
./1
├── 2
│ ├── test2.txt
│ └── test2_1.txt
└── 3
├── 4
│ └── test4.txt
└── test3.txt
希望獲取到的對(duì)象結(jié)構(gòu)如下:
{
root: {
path: './1',
type: 'folder',
children: ['2', '3'],
isRoot: true,
},
2: {
path: '2',
type: 'folder',
children: ['2/test2.txt', '2/test2_1.txt'],
},
3: { path: '3', type: 'folder', children: ['3/4', '3/test3.txt'] },
'2/test2.txt': { path: '2/test2.txt', type: 'file' },
'2/test2_1.txt': { path: '2/test2_1.txt', type: 'file' },
'3/4/test4.txt': { path: '3/4/test4.txt', type: 'folder', children: [] },
'3/4': { path: '3/4', type: 'folder', children: ['3/4/test4.txt'] },
'3/test3.txt': { path: '3/test3.txt', type: 'file' },
};
這個(gè)對(duì)象以文件/文件夾相對(duì)于根目錄的相對(duì)路徑為 key,每個(gè)節(jié)點(diǎn)包含了這些屬性:
- type:用于區(qū)分文件或文件夾類型
- path:相對(duì)路徑
- children:如果是文件夾類型,則其中是子文件的相對(duì)路徑
異步方式
在上面的實(shí)現(xiàn)中,都是使用了同步的方式來處理,即 fs.readdirSync 方法,可以使用異步方式來處理嗎?
可以選擇 fs.readdir 來異步讀取文件夾, 但是回調(diào)函數(shù)的調(diào)用方式不太方便。在 Node 10+ 中提供了 fs.promises API,其中提供了一些文件系統(tǒng)的方法,它們返回的是一個(gè) Promise 對(duì)象,而非使用回調(diào)函數(shù)。這里可以從 fs.promises 中引入 readdir 方法,從而可以使用方便的 async/await 語法來進(jìn)行異步處理,避免了回調(diào)函數(shù)的方式。
const { readdir } = require('fs').promises;
將上面的 traverseFolderList 方法重寫為異步格式:
比較同步和異步兩種方案
traverseFolderList 和 asyncTraverseFolderList 返回的結(jié)果都是列表格式,我們可以寫一個(gè)測試腳本來比較下二者的運(yùn)行時(shí)間:
分別用兩個(gè)函數(shù)遍歷了同一個(gè)文件夾十次后,統(tǒng)計(jì)結(jié)果如下,異步方式比同步方式減少了約18%的時(shí)間。
同步 - 平均耗時(shí):1217.1ms
異步 - 平均耗時(shí):1025.7ms
注意一點(diǎn),本文中的代碼都是沒有做錯(cuò)誤處理的,實(shí)際上讀取文件時(shí)可能會(huì)出錯(cuò),因此將相應(yīng)的代碼使用 try...catch 包起來是一個(gè)合理的做法。
附node遍歷文件夾并讀取文件內(nèi)容
var fs = require('fs');
var path = require('path');//解析需要遍歷的文件夾
var filePath = path.resolve('./dist');
//調(diào)用文件遍歷方法
fileDisplay(filePath);
//文件遍歷方法
function fileDisplay(filePath){undefined
//根據(jù)文件路徑讀取文件,返回文件列表
fs.readdir(filePath,function(err,files){undefined
if(err){undefined
console.warn(err)
}else{undefined
//遍歷讀取到的文件列表
files.forEach(function(filename){undefined
//獲取當(dāng)前文件的絕對(duì)路徑
var filedir = path.join(filePath, filename);
//根據(jù)文件路徑獲取文件信息,返回一個(gè)fs.Stats對(duì)象
fs.stat(filedir,function(eror, stats){undefined
if(eror){undefined
console.warn('獲取文件stats失敗');
}else{undefined
var isFile = stats.isFile();//是文件
var isDir = stats.isDirectory();//是文件夾
if(isFile){undefined
console.log(filedir); // 讀取文件內(nèi)容
var content = fs.readFileSync(filedir, 'utf-8');
console.log(content);
}
if(isDir){undefined
fileDisplay(filedir);//遞歸,如果是文件夾,就繼續(xù)遍歷該文件夾下面的文件
}
}
})
});
}
});
}
如果碰到有中文不能解析的html,這樣寫
var cheerio = require('cheerio');
var iconv = require('iconv-lite');
var myHtml = fs.readFileSync("index.html");
var myHtml2 = iconv.decode(myHtml, 'gbk');
console.log(myHtml2);參考資料
https://stackoverflow.com/a/45130990
https://javascript.info/promisify
總結(jié)
到此這篇關(guān)于如何使用Node.js遍歷文件夾的文章就介紹到這了,更多相關(guān)Node.js遍歷文件夾內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
HTTP JSON接口模擬工具Interfake快速入門教程
這篇文章主要為大家介紹了HTTP JSON接口模擬工具Interfake快速入門教程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-06-06
Node.js實(shí)現(xiàn)數(shù)據(jù)推送
這篇文章主要為大家詳細(xì)介紹了Node.js實(shí)現(xiàn)數(shù)據(jù)推送的相關(guān)資料,感興趣的小伙伴們可以參考一下2016-04-04
使用nodeJs來安裝less及編譯less文件為css文件的方法
這篇文章主要介紹了使用nodeJs來安裝less及編譯less文件為css文件的方法,在文章末尾給大家補(bǔ)充介紹了通過nodejs將less文件轉(zhuǎn)為css文件的方法,具體內(nèi)容詳情大家通過本文學(xué)習(xí)吧2017-11-11
基于html5和nodejs相結(jié)合實(shí)現(xiàn)websocket即使通訊
HTML5 擁有許多引人注目的新特性,如 Canvas、本地存儲(chǔ)、多媒體編程接口、WebSocket 等等。雖然現(xiàn)在大家把它捧的很火的樣子,但是個(gè)人認(rèn)為它還需要其他平臺(tái)的支持才能真正的"火起來"2015-11-11
在Ubuntu系統(tǒng)上安裝Ghost博客平臺(tái)的教程
這篇文章主要介紹了在Ubuntu系統(tǒng)上安裝Ghost博客平臺(tái)的教程,Ghost博客平臺(tái)以Node.js寫成,需要的朋友可以參考下2015-06-06
Node.js中Express生成Token的實(shí)現(xiàn)方法
本文介紹了在Express中生成和使用Token進(jìn)行用戶認(rèn)證的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-12-12

