const fs = require('fs'); const path = require('path'); const readline = require('readline'); const performanceMonitor = require('./performance'); /** * 大文件处理模块 * 使用流(Stream)处理大文件,避免一次性加载到内存导致溢出 */ class LargeFileHandler { constructor(filePath) { this.filePath = filePath; } /** * 生成测试用的大文件 * @param {number} lines - 行数 */ async generateTestFile(lines = 100000) { performanceMonitor.start('生成大文件'); return new Promise((resolve, reject) => { const stream = fs.createWriteStream(this.filePath); // 使用 Buffer 写入可以提高性能,但为了演示简单这里直接写字符串 for (let i = 0; i < lines; i++) { // 模拟 CSV 格式数据:ID,Name,Timestamp,Value const data = `${i},User_${i},${Date.now()},${Math.random() * 1000}\n`; if (!stream.write(data)) { // 如果缓冲区满了,等待 drain 事件 // 这里为了简化演示没有处理背压(backpressure),实际生产中应该处理 } } stream.end(); stream.on('finish', () => { performanceMonitor.end('生成大文件'); console.log(`[大文件] 已生成测试文件: ${this.filePath}`); resolve(); }); stream.on('error', reject); }); } /** * 使用流读取并处理大文件 * 演示逐行读取并进行简单的数据聚合 */ async processFileStream() { performanceMonitor.start('流式处理大文件'); const fileStream = fs.createReadStream(this.filePath); const rl = readline.createInterface({ input: fileStream, crlfDelay: Infinity }); let lineCount = 0; let sumValue = 0; for await (const line of rl) { lineCount++; // 简单的处理逻辑:解析每行数据并累加 Value 字段 const parts = line.split(','); if (parts.length >= 4) { sumValue += parseFloat(parts[3]); } } console.log(`[大文件] 处理完成。总行数: ${lineCount}, Value总和: ${sumValue.toFixed(2)}`); performanceMonitor.end('流式处理大文件'); } /** * 对比测试:尝试一次性读取(慎用,可能会导致内存溢出) * 仅用于展示小文件或性能对比 */ async processFileSync() { console.log('[大文件] 警告:尝试一次性读取文件(不推荐用于大文件)...'); try { performanceMonitor.start('同步读取文件'); const data = fs.readFileSync(this.filePath, 'utf-8'); const lines = data.split('\n'); let sumValue = 0; lines.forEach(line => { if (!line) return; const parts = line.split(','); if (parts.length >= 4) { sumValue += parseFloat(parts[3]); } }); console.log(`[大文件] 同步处理完成。Value总和: ${sumValue.toFixed(2)}`); performanceMonitor.end('同步读取文件'); } catch (err) { console.error('[大文件] 读取失败:', err.message); } } } module.exports = LargeFileHandler;