一、代码核心作用
-
目录遍历
- 递归扫描
./src目录及其子目录 - 自动跳过图片文件 (
.png,.jpg等)、字体文件 (.ttf,.woff等) 和 Markdown 文件 (.md)
- 递归扫描
-
内容聚合
-
读取所有文本类型文件内容 (如
.js,.html,.css等) -
过滤空行后按以下格式记录每个文件:
File: 文件名路径 Content: 文件内容(保留非空行) ---
-
-
文件分割
-
当累计行数超过阈值(默认
15000行)时:- 将已收集的内容写入
output_序号.txt文件 - 重置计数器和缓存,继续处理剩余文件
- 将已收集的内容写入
-
二、关键代码逻辑说明
1. 文件筛选机制
// 跳过图片文件
if (['.png', '.jpg', ..., '.svg'].includes(ext)) continue;
// 跳过字体文件
if (['.ttf', '.otf', ..., '.eot'].includes(ext)) continue;
// 跳过Markdown
if (['.md'].includes(ext)) continue;
2. 行数统计与分割
// 按非空行统计
const lines = content.split('\n').filter(line => line.trim() !== '');
lineCount += lines.length;
// 超过阈值时触发写入
if (lineCount > totalLines) break;
3. 输出文件格式
// 每个文件的记录格式
`File: ${item.filename}\n\nContent:\n${item.content}\n\n---\n`
三、典型使用场景
-
代码仓库分析
- 将项目源代码聚合为可搜索的文本档案
-
日志处理
- 合并分散的日志文件并按大小分割存储
-
文档预处理
- 为 NLP 任务准备训练语料库
四、执行示例
假设 ./src 包含:
src/
app.js (30行)
utils/
math.js (20行)
config.json (10行)
运行后生成 output_1.txt:
File: src/app.js
Content:
const fs = require('fs');
...(其他非空行)
---
File: src/utils/math.js
Content:
function add(a, b) {
...(其他非空行)
---
五、代码
const fs = require('fs')
const path = require('path')
// 异步遍历目录函数,接受目录路径和总行数作为参数
const traverseDirectory = async (dirPath, totalLines = 4000) => {
let allResults = [] // 存储所有文件的结果
let lineCount = 0 // 当前文件的行数计数
let fileIndex = 1 // 输出文件的索引
// 将当前结果写入文件的函数
const writeToFile = () => {
if (allResults.length > 0) {
const output = allResults
.map((item) => `File: ${item.filename}\n\nContent:\n${item.content}\n\n---\n`)
.join('\n')
fs.writeFileSync(`output_${fileIndex}.txt`, output)
fileIndex++
allResults = []
lineCount = 0
}
}
// 递归遍历目录的函数
const traverse = async (currentPath) => {
const files = fs.readdirSync(currentPath) // 读取当前目录中的所有文件
for (const file of files) {
const fullPath = path.join(currentPath, file) // 获取文件的完整路径
const stat = fs.statSync(fullPath) // 获取文件的状态信息
if (stat.isDirectory()) {
await traverse(fullPath) // 如果是目录,递归遍历
} else {
const ext = path.extname(fullPath).toLowerCase() // 获取文件扩展名
if (['.png', '.jpg', '.jpeg', '.gif', '.bmp', '.svg'].includes(ext)) {
continue // 忽略图片文件
}
if (['.ttf', '.otf', '.woff', '.woff2', '.eot', '.svg'].includes(ext)) {
continue // 忽略字体文件
}
if (['.md'].includes(ext)) {
continue // 忽略markdown文件
}
const content = fs.readFileSync(fullPath, 'utf8') // 读取文件内容
const lines = content.split('\n').filter((line) => line.trim() !== '') // 按行分割并过滤空行
allResults.push({
filename: fullPath,
content: lines.join('\n'),
})
lineCount += lines.length // 更新行数计数
if (lineCount > totalLines) {
break // 如果当前文件的行数超过总行数,停止遍历
}
}
}
}
await traverse(dirPath) // 开始遍历指定目录
// 写入剩余内容
writeToFile()
}
// 使用示例
const targetDirectory = './src'
const totalLines = 15000 // 生成文件的总行数
traverseDirectory(targetDirectory, totalLines)