对于下面的所有示例,您需要导入fs和路径模块:
const fs = require('fs');
const path = require('path');
异步读取文件
function readFiles(dir, processFile) {
// read directory
fs.readdir(dir, (error, fileNames) => {
if (error) throw error;
fileNames.forEach(filename => {
// get current file name
const name = path.parse(filename).name;
// get current file extension
const ext = path.parse(filename).ext;
// get current file path
const filepath = path.resolve(dir, filename);
// get information about the file
fs.stat(filepath, function(error, stat) {
if (error) throw error;
// check if the current path is a file or a folder
const isFile = stat.isFile();
// exclude folders
if (isFile) {
// callback, do something with the file
processFile(filepath, name, ext, stat);
}
});
});
});
}
用法:
// use an absolute path to the folder where files are located
readFiles('absolute/path/to/directory/', (filepath, name, ext, stat) => {
console.log('file path:', filepath);
console.log('file name:', name);
console.log('file extension:', ext);
console.log('file information:', stat);
});
同步读取文件,存储在数组中,自然排序
/**
* @description Read files synchronously from a folder, with natural sorting
* @param {String} dir Absolute path to directory
* @returns {Object[]} List of object, each object represent a file
* structured like so: `{ filepath, name, ext, stat }`
*/
function readFilesSync(dir) {
const files = [];
fs.readdirSync(dir).forEach(filename => {
const name = path.parse(filename).name;
const ext = path.parse(filename).ext;
const filepath = path.resolve(dir, filename);
const stat = fs.statSync(filepath);
const isFile = stat.isFile();
if (isFile) files.push({ filepath, name, ext, stat });
});
files.sort((a, b) => {
// natural sort alphanumeric strings
// https://stackoverflow.com/a/38641281
return a.name.localeCompare(b.name, undefined, { numeric: true, sensitivity: 'base' });
});
return files;
}
用法:
// return an array list of objects
// each object represent a file
const files = readFilesSync('absolute/path/to/directory/');
使用 promise 异步读取文件
本文中有关Promisify的更多信息。
const { promisify } = require('util');
const readdir_promise = promisify(fs.readdir);
const stat_promise = promisify(fs.stat);
function readFilesAsync(dir) {
return readdir_promise(dir, { encoding: 'utf8' })
.then(filenames => {
const files = getFiles(dir, filenames);
return Promise.all(files);
})
.catch(err => console.error(err));
}
function getFiles(dir, filenames) {
return filenames.map(filename => {
const name = path.parse(filename).name;
const ext = path.parse(filename).ext;
const filepath = path.resolve(dir, filename);
return stat({ name, ext, filepath });
});
}
function stat({ name, ext, filepath }) {
return stat_promise(filepath)
.then(stat => {
const isFile = stat.isFile();
if (isFile) return { name, ext, filepath, stat };
})
.catch(err => console.error(err));
}
用法:
readFiles('absolute/path/to/directory/')
// return an array list of objects
// each object is a file
// with those properties: { name, ext, filepath, stat }
.then(files => console.log(files))
.catch(err => console.log(err));
注意:返回undefined
文件夹,如果需要,可以将它们过滤掉:
readFiles('absolute/path/to/directory/')
.then(files => files.filter(file => file !== undefined))
.catch(err => console.log(err));