当前位置: 首页 > ds >正文

NodeJS读写(同步异步、流式、分片策略)

Node.js文件读写操作核心API及模式详解


一、基础文件读写API

  1. 同步操作
    • API:fs.readFileSync() / fs.writeFileSync()

    • 特点:阻塞主线程,适合处理小文件(<1MB)或启动初始化

    • 示例:

    const data = fs.readFileSync('config.json', 'utf8');
    fs.writeFileSync('backup.json', data);
    
  2. 异步回调
    • API:fs.readFile() / fs.writeFile()

    • 特点:非阻塞,需通过回调处理结果,易引发“回调地狱”

    • 示例:

    fs.readFile('log.txt', (err, data) => {if (err) throw err;fs.writeFile('log_backup.txt', data, () => {});
    });
    
  3. Promise形式
    • API:fs.promises.readFile() / fs.promises.writeFile()

    • 特点:配合async/await使用,代码结构更清晰

    • 示例:

    async function processFile() {const data = await fs.promises.readFile('data.csv');await fs.promises.writeFile('processed.csv', data);
    }
    

二、同步与异步模式对比

维度同步操作异步操作
执行方式阻塞主线程非阻塞,后台I/O线程池处理
适用场景配置文件加载、初始化数据大文件处理、高并发请求
内存占用直接加载全量数据分块处理,内存压力小
错误处理try/catch捕获回调参数或Promise链式捕获
性能影响导致界面卡顿保持应用响应流畅

三、流式操作(处理大文件核心方案)

  1. 读取流
    • API:fs.createReadStream()

    • 特性:分块读取(默认64KB/块),支持highWaterMark调整缓冲区

    • 示例:

    const readStream = fs.createReadStream('video.mp4', { highWaterMark: 128*1024 });
    readStream.on('data', (chunk) => { /* 处理数据块 */ });
    
  2. 写入流
    • API:fs.createWriteStream()

    • 特性:自动处理背压,支持追加模式

    • 示例:

    const writeStream = fs.createWriteStream('output.log', { flags: 'a' });
    writeStream.write('日志内容\n');
    
  3. 管道流
    • API:readStream.pipe(writeStream)

    • 应用:实现文件复制、数据压缩等链式操作

    • 示例(GZIP压缩):

    fs.createReadStream('data.txt').pipe(zlib.createGzip()).pipe(fs.createWriteStream('data.txt.gz'));
    

四、高级技巧

  1. 内存映射
    • API:fs.open() + fs.read()

    • 场景:高频随机访问大文件(如数据库索引)

    • 优势:直接操作内存缓冲区,避免多次磁盘I/O

    const fd = fs.openSync('large.bin', 'r');
    const buffer = Buffer.alloc(1024);
    fs.read(fd, buffer, 0, 1024, 0);
    
  2. 错误处理规范
    • 同步操作必须用try/catch包裹

    • 异步流操作需监听error事件:

    readStream.on('error', (err) => console.error('读取失败:', err));
    writeStream.on('error', (err) => console.error('写入失败:', err));
    
  3. 性能优化参数
    highWaterMark:调整流缓冲区大小(如设置128MB分块)

    autoClose:流结束后自动关闭文件描述符

    emitClose:确保流关闭事件触发

    fs.createReadStream('data.bin', { highWaterMark: 128*1024*1024 });
    

五、模式选择建议

  1. 小文件(<10MB):
    • 优先使用fs.promises的Promise API

    • 同步操作仅限程序启动阶段

  2. 中型文件(10MB~1GB):
    • 采用流式分块处理

    • 结合pipeline方法提升吞吐量

  3. 超大文件(>1GB):
    • 必须使用流式操作

    • 结合内存映射+Worker线程并行处理

通过合理选择API和模式,可显著提升Node.js文件处理性能。对于日志分析、视频处理等场景,推荐优先采用流式+管道组合方案。


以下是基于不同文件规模选择 Node.js 文件操作模式的实例代码及解析:


一、小文件(<10MB)

  1. Promise API 异步读写
const fs = require('fs').promises;// 读取并复制小文件
async function processSmallFile() {try {const data = await fs.readFile('config.json', 'utf8');await fs.writeFile('config_backup.json', data);console.log('小文件操作完成');} catch (err) {console.error('错误:', err.message);}
}
processSmallFile();

特点:
• 使用 fs.promises 的 Promise 接口,代码简洁

• 适合配置文件、初始化数据等场景

  1. 同步操作(仅限启动阶段)
const fs = require('fs');try {const config = fs.readFileSync('env.prod', 'utf8');fs.writeFileSync('env.backup', config);console.log('启动阶段同步操作完成');
} catch (err) {console.error('同步错误:', err.message);
}

注意:同步操作会阻塞事件循环,仅建议在程序初始化时使用


二、中型文件(10MB~1GB)

  1. 流式分块处理 + pipeline
const fs = require('fs');
const { pipeline } = require('stream/promises');
const zlib = require('zlib');// 流式压缩文件
async function processMediumFile() {try {await pipeline(fs.createReadStream('data.log', { highWaterMark: 128 * 1024 }), // 128KB分块zlib.createGzip(),fs.createWriteStream('data.log.gz'));console.log('中型文件压缩完成');} catch (err) {console.error('流处理错误:', err);}
}
processMediumFile();

优化点:
pipeline 自动处理背压和错误传播

highWaterMark 调整缓冲区大小提升吞吐量

  1. 逐行处理日志文件
const fs = require('fs');
const readline = require('readline');const rl = readline.createInterface({input: fs.createReadStream('access.log'),crlfDelay: Infinity
});rl.on('line', (line) => {if (line.includes('ERROR')) {fs.appendFileSync('errors.log', line + '\n');}
});
rl.on('close', () => console.log('日志分析完成'));

适用场景:日志过滤、CSV 数据处理等


三、超大文件(>1GB)

  1. 流式操作 + 内存映射
const fs = require('fs');
const { Worker, isMainThread } = require('worker_threads');// 主线程:分片处理
if (isMainThread) {const CHUNK_SIZE = 512 * 1024 * 1024; // 512MB分片const fd = fs.openSync('huge_dataset.bin', 'r');const stats = fs.fstatSync(fd);for (let i = 0; i < stats.size; i += CHUNK_SIZE) {new Worker(__filename, {workerData: { fd, offset: i, chunkSize: CHUNK_SIZE }});}
} 
// Worker线程:内存映射读取
else {const { fd, offset, chunkSize } = workerData;const buffer = Buffer.alloc(chunkSize);fs.read(fd, buffer, 0, chunkSize, offset, (err) => {if (err) throw err;processBufferData(buffer); // 自定义处理逻辑fs.closeSync(fd);});
}

核心技术:
• 内存映射减少磁盘 I/O 次数

• Worker 线程实现并行处理

  1. 分块流式备份
const fs = require('fs');async function backupLargeFile() {const readStream = fs.createReadStream('big_db.dump', {highWaterMark: 256 * 1024 * 1024 // 256MB缓冲区});const writeStream = fs.createWriteStream('backup.dump');readStream.on('data', (chunk) => {if (!writeStream.write(chunk)) {readStream.pause(); // 背压控制}});writeStream.on('drain', () => readStream.resume());
}
backupLargeFile();

特点:
• 手动背压控制保障内存安全

• 适合数据库备份等场景


关键参数对比表

文件规模核心 API内存占用适用场景
<10MBfs.promises全量加载配置文件、初始化数据
10MB~1GBcreateReadStream + pipeline分块缓冲日志分析、CSV 处理
>1GB内存映射 + Worker 线程分片映射大数据处理、视频转码

最佳实践建议:

  1. 流式操作始终添加 error 事件监听
  2. 通过 highWaterMark 按硬件配置调整缓冲区
  3. 超过 2GB 文件必须使用分片策略
http://www.xdnf.cn/news/3184.html

相关文章:

  • CentOS环境下搭建seata(二进制、MySQL)
  • 安装deepspeed时出现了以下的错误,如何解决CUDA_HOME does not exist
  • vue3+flex动态的绘制蛇形时间轴
  • 远程桌面导致Quartus 破解失效
  • Silvaco仿真中的victory mesh
  • 【MySQL数据库】--1.安装教程
  • HHsuite同源序列搜索数据库构建
  • 如何在Windows中更改文档默认打开方式
  • 【保姆级教程-Centos7环境下部署Prometheus并设置开机自启】
  • 【Yolo精读+实践+魔改系列】Yolov2论文超详细精讲(翻译+笔记)
  • temu,shein采购测评避坑指南:如何避免砍单封号,实现长效运营?
  • Harbor默认Redis与Notary组件弱口令漏洞分析与修复指南
  • ​【空间数据分析】缓冲区分析--泰森多边形(Voronoi Diagram)-arcgis操作
  • labview项目文件架构
  • WSL2下Docker desktop的Cadvisor容器监控
  • Spring Security 的 CSRF 防护机制
  • 时态--09--动词过去式、过去分词
  • 搜索——哈希优化策略
  • MTK Genio500 移植GMS及youtube问题处理的解决办法
  • docker拉取国内镜像
  • Javascript 中的继承?如何实现继承?
  • 解密Cloak斗篷技术:FP独立站推广利器
  • [论文阅读]Adversarial Semantic Collisions
  • 为什么要学习《易经》?
  • 大模型核心技术及架构解析
  • Android Q允许低内存启用系统弹窗
  • 蓝桥杯算法开发企业级实战指导:从0到1的C/C++全攻略
  • kubelet 清理资源以缓解磁盘压力
  • 考OCM证书前需要有OCP证书
  • 再谈cookie和session(结合表白墙具体案例)