如何使用Node.js遍歷文件夾詳解
前言
最近在寫一個管理 markdown 文件的工具 knowledge-center,需要讀取指定文件夾內所有 markdown 文件。因此需要用 Node.js 來實現遍歷一個文件夾內所有文件的功能。
Node.js 中提供了這些有用的 API:
- fs.readdir:異步讀取文件夾
- fs.readdirSync:同步讀取文件夾
- fs.statSync:同步獲取文件屬性
獲取的文件列表為數組格式
對于遍歷的結果,我們可以選擇按列表或文件樹來展示。先從最簡單的情況看起,用同步方式處理,返回結果是一個列表。
先使用 fs.readdirSync 獲取文件列表,然后遍歷文件列表,使用 fs.statSync 獲取列表中文件的狀態(tài),如果是文件,則添加到文件列表中,如果是文件夾,則遞歸調用 traverseFolderList 函數,直到獲取到所有文件。
獲取的文件列表為對象格式
如果我們想展示文件夾目錄結構,那么列表格式的就不太方便了。假設有如下的文件夾結構:
./1
├── 2
│ ├── test2.txt
│ └── test2_1.txt
└── 3
├── 4
│ └── test4.txt
└── test3.txt
希望獲取到的對象結構如下:
{
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' },
};
這個對象以文件/文件夾相對于根目錄的相對路徑為 key,每個節(jié)點包含了這些屬性:
- type:用于區(qū)分文件或文件夾類型
- path:相對路徑
- children:如果是文件夾類型,則其中是子文件的相對路徑
異步方式
在上面的實現中,都是使用了同步的方式來處理,即 fs.readdirSync 方法,可以使用異步方式來處理嗎?
可以選擇 fs.readdir 來異步讀取文件夾, 但是回調函數的調用方式不太方便。在 Node 10+ 中提供了 fs.promises API,其中提供了一些文件系統(tǒng)的方法,它們返回的是一個 Promise 對象,而非使用回調函數。這里可以從 fs.promises 中引入 readdir 方法,從而可以使用方便的 async/await 語法來進行異步處理,避免了回調函數的方式。
const { readdir } = require('fs').promises;
將上面的 traverseFolderList 方法重寫為異步格式:
比較同步和異步兩種方案
traverseFolderList 和 asyncTraverseFolderList 返回的結果都是列表格式,我們可以寫一個測試腳本來比較下二者的運行時間:
分別用兩個函數遍歷了同一個文件夾十次后,統(tǒng)計結果如下,異步方式比同步方式減少了約18%的時間。
同步 - 平均耗時:1217.1ms
異步 - 平均耗時:1025.7ms
注意一點,本文中的代碼都是沒有做錯誤處理的,實際上讀取文件時可能會出錯,因此將相應的代碼使用 try...catch 包起來是一個合理的做法。
附node遍歷文件夾并讀取文件內容
var fs = require('fs');
var path = require('path');//解析需要遍歷的文件夾
var filePath = path.resolve('./dist');
//調用文件遍歷方法
fileDisplay(filePath);
//文件遍歷方法
function fileDisplay(filePath){undefined
//根據文件路徑讀取文件,返回文件列表
fs.readdir(filePath,function(err,files){undefined
if(err){undefined
console.warn(err)
}else{undefined
//遍歷讀取到的文件列表
files.forEach(function(filename){undefined
//獲取當前文件的絕對路徑
var filedir = path.join(filePath, filename);
//根據文件路徑獲取文件信息,返回一個fs.Stats對象
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); // 讀取文件內容
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
總結
到此這篇關于如何使用Node.js遍歷文件夾的文章就介紹到這了,更多相關Node.js遍歷文件夾內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Node.js?搭建后端服務器內置模塊(?http+url+querystring?的使用)
這篇文章主要介紹了Node.js搭建后端服務器內置模塊(http+url+querystring的使用),文章圍繞主題展開詳細的內容戒殺,具有一定的參考價值,需要的朋友可以參考一下2022-09-09
Vue+Node服務器查詢Mongo數據庫及頁面數據傳遞操作實例分析
這篇文章主要介紹了Vue+Node服務器查詢Mongo數據庫及頁面數據傳遞操作,結合實例形式分析了node.js查詢MongoDB數據庫及vue前臺頁面渲染等相關操作技巧,需要的朋友可以參考下2019-12-12
express如何解決ajax跨域訪問session失效問題詳解
這篇文章主要給大家介紹了關于express如何解決ajax跨域訪問session失效問題的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧2019-06-06

