我试图创建一个搜索所有文件的应用 包含当前目录/子目录下的指定字符串。
据我所知,这意味着我需要创建一个读取流,循环它,将读取数据加载到一个数组,如果找到的话给__filename,dirname和if!没找到消息。
不幸的是,我无法让它发挥作用...... 任何线索?
var path = require('path'),
fs=require('fs');
function fromDir(startPath,filter,ext){
if (!fs.existsSync(startPath)){
console.log("no dir ",startPath);
return;
};
var files=fs.readdirSync(startPath);
let found = files.find((file) => {
let thisFilename = path.join(startPath, file);
let stat = fs.lstatSync(thisFilename);
var readStream = fs.createReadStream(fs);
var readline = require('readline');
if (stat.isDirectory()) {
fromDir(thisFilename, filename,readline, ext);
} else {
if (path.extname(createReadStream) === ext && path.basename(thisFilename, ext) === filename) {
return true;
}
}
});
console.log('-- your word has found on : ',filename,__dirname);
}
if (!found) {
console.log("Sorry, we didn't find your term");
}
}
fromDir('./', process.argv[3], process.argv[2]);

答案 0 :(得分:4)
因为并非所有内容都包含在问题中,所以我做了一个假设:
我们正在寻找完整的字词(如果情况并非如此,则用简单的
indexOf()
替换正则表达式。)
现在,我已将代码拆分为两个函数 - 使其更易读,更容易递归查找文件。
同步版本:
const path = require('path');
const fs = require('fs');
function searchFilesInDirectory(dir, filter, ext) {
if (!fs.existsSync(dir)) {
console.log(`Specified directory: ${dir} does not exist`);
return;
}
const files = fs.readdirSync(dir);
const found = getFilesInDirectory(dir, ext);
found.forEach(file => {
const fileContent = fs.readFileSync(file);
// We want full words, so we use full word boundary in regex.
const regex = new RegExp('\\b' + filter + '\\b');
if (regex.test(fileContent)) {
console.log(`Your word was found in file: ${file}`);
}
});
}
// Using recursion, we find every file with the desired extention, even if its deeply nested in subfolders.
function getFilesInDirectory(dir, ext) {
if (!fs.existsSync(dir)) {
console.log(`Specified directory: ${dir} does not exist`);
return;
}
let files = [];
fs.readdirSync(dir).forEach(file => {
const filePath = path.join(dir, file);
const stat = fs.lstatSync(filePath);
// If we hit a directory, apply our function to that dir. If we hit a file, add it to the array of files.
if (stat.isDirectory()) {
const nestedFiles = getFilesInDirectory(filePath, ext);
files = files.concat(nestedFiles);
} else {
if (path.extname(file) === ext) {
files.push(filePath);
}
}
});
return files;
}
异步版 - 因为async
很酷:
const path = require('path');
const fs = require('fs');
const fsReaddir = util.promisify(fs.readdir);
const fsReadFile = util.promisify(fs.readFile);
const fsLstat = util.promisify(fs.lstat);
async function searchFilesInDirectoryAsync(dir, filter, ext) {
const files = await fsReaddir(dir).catch(err => {
throw new Error(err.message);
});
const found = await getFilesInDirectoryAsync(dir, ext);
for (file of found) {
const fileContent = await fsReadFile(file);
// We want full words, so we use full word boundary in regex.
const regex = new RegExp('\\b' + filter + '\\b');
if (regex.test(fileContent)) {
console.log(`Your word was found in file: ${file}`);
}
};
}
// Using recursion, we find every file with the desired extention, even if its deeply nested in subfolders.
async function getFilesInDirectoryAsync(dir, ext) {
let files = [];
const filesFromDirectory = await fsReaddir(dir).catch(err => {
throw new Error(err.message);
});
for (let file of filesFromDirectory) {
const filePath = path.join(dir, file);
const stat = await fsLstat(filePath);
// If we hit a directory, apply our function to that dir. If we hit a file, add it to the array of files.
if (stat.isDirectory()) {
const nestedFiles = await getFilesInDirectoryAsync(filePath, ext);
files = files.concat(nestedFiles);
} else {
if (path.extname(file) === ext) {
files.push(filePath);
}
}
};
return files;
}
如果您尚未使用/了解async / await,那么这是一个很好的步骤,可以尽快学习它。相信我,你会爱不再看到那些丑陋的回调!
<强>更新强>
正如您在注释中指出的那样,您希望它在对文件运行node
进程后执行该函数。您还希望将函数参数作为node
的参数传递。
要做到这一点,在文件的末尾,您需要添加:
searchFilesInDirectory(process.argv[2], process.argv[3], process.argv[4]);
这会提取我们的参数并将它们传递给函数。
有了这个,你可以这样调用我们的过程(示例参数):
node yourscriptname.js ./ james .txt
就个人而言,如果我写这篇文章,我会利用异步代码的优点,以及Node.js的async / await
。
作为一个侧面说明:
如果为其添加适当的格式,则可以轻松提高代码的可读性。不要误解我,这并不可怕 - 但可以改进:
只要您与格式保持一致,一切看起来都会好一些。