file-info
Version:
Traverse the current directory and display the file information.
146 lines (138 loc) • 5.61 kB
JavaScript
const path=require('path');
const fs=require('fs');
const process=require('process');
const ignore=new Set(['node_modules','.git','.DS_Store']);
const filePath=path.dirname(process.argv[1]);
/**
* 判断此文件是否为文本文件
* @param {String} filePath 文件路径
* @param {Number} [testLength=1000] 判断精度,默认前1000字节
* @return {Boolean} 返回判断结果,true为文本文件
*/
function isTextFile(filePath,testLength=1000){
const bf=fs.readFileSync(filePath);
const byteLength=Buffer.byteLength(bf);
if(byteLength>1000){
testLength=1000;
}else{
testLength=byteLength;
}
const fd=fs.openSync(filePath,'r');
for(let i=0;i<byteLength;i++){
if(bf[i].toString()==='0'){
return false;
}
}
return true;
}
/**
* 获取文件夹目录数组
* @param {String} [use_path=''] 文件夹路径
* @param {Array} [ignoreArr=[]] 忽略的文件夹
* @param {Boolean} [isIgnore=true] 是否忽略默认文件夹,默认为true
* @return {Array} 返回一个Promise对象,回调函数参数为文件夹数组
*/
function showList(use_path='',ignoreArr=[],isIgnore=true){
let ignore_set;
let filePathFn='';
let returnList=[];
if(isIgnore){
ignore_set=new Set([...ignore,...ignoreArr]);
}else{
ignore_set=new Set([...ignoreArr]);
}
if(!use_path){
filePathFn=filePath;
}else{
filePathFn=path.resolve(filePath,use_path);
}
console.log('File list info:');
console.log('文件夹:',filePathFn);
//根据用户的输入地址,返回一条绝对路径
return new Promise(function(resolve,reject){
fs.stat(filePathFn,(err,data)=>{
if(err){
reject(err);
return ;
// throw new Error('不存在这个文件夹');
}
if(!data.isDirectory()){
throw new Error('Please enter a folder path');
}
resolve(filePathFn);
});
}).then(function(data){
//data:处理错的路径
let all_file=new Set();
var showFileAddr=function(filePathFn){
const fileArr=fs.readdirSync(filePathFn);
fileArr.forEach((item,index,arr)=>{
if(!ignore_set.has(item)){
try {
//文件或文件夹数组
const itemPath=fs.statSync(path.join(filePathFn,item));
if(itemPath.isFile()){
all_file.add(path.join(filePathFn,item));
}
if(itemPath.isDirectory()){
//子文件夹过的文件数组
const newDir=fs.readdirSync(path.join(filePathFn,item));
showFileAddr(path.join(filePathFn,item));
}
} catch (e) {
throw new Error(e);
}
}
});
};
showFileAddr(data);
return all_file;
}).then(function(data){
returnList=[...data];
// console.log(returnList);
return returnList;
}).catch(function(err){
console.log(err);
});
}
/**
* 获取文件夹详细信息
* @param {String} [use_path=''] 文件夹路径
* @param {Array} [ignoreArr=[]] 忽略的文件数组
* @param {Boolean} [isIgnore=true] 是否忽略默认文件夹
* @return {Array} 返回一个Promise对象,回调函数参数为数组,包括所有文件总行数、总中文字数、总英文字数、总标点符号数以及文件总大小(totalLine、chineseNum、endlishNum、sizeNum)
*/
function showDetail(use_path='',ignoreArr=[],isIgnore=true){
return showList(use_path,ignore,isIgnore).then((data)=>{
//总行数、中文总数、英文总数、标点符号总数、文件大小
let totalLine=0;
let chineseNum=0;
let endlishNum=0;
let punctuationNum=0;
let sizeNum=0;
data.forEach((item,index,arr)=>{
if(isTextFile(item)){
let itemInfo=fs.statSync(item);
let itemString=fs.readFileSync(item,'utf8');
//获取内容
let itemStringLine=itemString.match(/\n/g)?itemString.match(/\n/g).length:1;
let chineseStr=itemString.toString().match(/[\u4E00-\u9FA5\uF900-\uFA2D]+/g);
let endlishStr=itemString.toString().match(/[a-zA-Z0-9]+/g);
let punctuationStr=itemString.toString().match(/[\^\$\(\)\*\+\?\.\[\\\{\|,``~\-_=。?!,、;:“”‘()《》〈〉【】『』「」]+/g);
//统计总数
totalLine+=itemStringLine;
chineseNum+=chineseStr?chineseStr.join('').length:0;
endlishNum+=endlishStr?endlishStr.join('').length:0;
punctuationNum+=punctuationStr?punctuationStr.join('').length:0;
sizeNum+=itemInfo.size;
}
});
console.log('总行数:',totalLine);
console.log('中文总数:',chineseNum);
console.log('英文及数字总数:',endlishNum);
console.log('标点符号总数:',punctuationNum);
console.log(`文件大小:${sizeNum}B(≈=${(sizeNum/1024).toFixed(2)}K)`);
return {totalLine,chineseNum,endlishNum,sizeNum};
});
}
module.exports={showList,showDetail};