File size: 3,559 Bytes
1b21241
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
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;