网站建设解决方案三亚网站建设

邱县一宁种植有限公司 2026/09/09 18:42:14

fs.promises是 Node.jsfs模块提供的Promise 化文件系统 API,替代了传统的回调式fs方法,天然适配async/await语法,是现代 Node.js 开发中处理文件系统的首选方式。

一、核心基础

1. 兼容性

  • Node.js v10.0.0 起,fs.promises被标记为稳定版;
  • Node.js v14.0.0 起,支持import fs from 'fs/promises'(更简洁的导入方式)。

2. ESM 配置前提

使用 ESM 格式(import/export)需满足以下任一条件:

  • 将文件后缀改为.mjs
  • 在项目根目录的package.json中添加"type": "module"

3. 导入方式

推荐使用更简洁的方式(Node.js 14+):

// 推荐:直接导入 promises 模块importfsfrom'fs/promises';// 配合路径处理(ESM 内置模块)importpathfrom'path';

兼容更低版本(Node.js 10+):

import{promisesasfs}from'fs';importpathfrom'path';

二、核心方法 & 代码示例

(一)文件基础操作

1. 读取文件(fs.readFile)

读取文件内容,支持文本/二进制格式,参数说明:

  • path:文件路径(推荐用path.resolve处理);
  • options:可选,包含encoding(编码,如utf8)、flag(操作模式,如r只读)。

示例1:读取文本文件

asyncfunctionreadTextFile(){// 绝对路径(避免相对路径陷阱)constfilePath=path.resolve(__dirname,'example.txt');try{constcontent=awaitfs.readFile(filePath,{encoding:'utf8',// 文本编码,省略则返回 Bufferflag:'r'// 只读模式(默认)});console.log('文件内容:
',content);}catch(err){console.error('读取失败:',err.message);}}readTextFile();

示例2:读取二进制文件(图片/视频)

asyncfunctionreadBinaryFile(){constimgPath=path.resolve(__dirname,'image.png');try{// 不指定 encoding,返回 Bufferconstbuffer=awaitfs.readFile(imgPath);console.log('文件大小:',buffer.length,'字节');// 可直接写入新文件(复制二进制文件)awaitfs.writeFile(path.resolve(__dirname,'copy-image.png'),buffer);}catch(err){console.error('读取二进制文件失败:',err.message);}}readBinaryFile();
2. 写入文件(fs.writeFile)

写入内容到文件,默认覆盖原有内容,参数说明:

  • path:目标文件路径;
  • data:写入内容(字符串/Buffer/Uint8Array);
  • options:可选,包含encodingflagw覆盖、a追加、wx原子写入(文件存在则失败))、mode(文件权限,如0o644)。

示例:写入/追加文件

asyncfunctionwriteFileExample(){constfilePath=path.resolve(__dirname,'output.txt');constcontent=`Hello fs.promises! 当前时间:${newDate().toISOString()}`;try{// 1. 覆盖写入(默认 flag: 'w')awaitfs.writeFile(filePath,content,{encoding:'utf8',mode:0o644// 权限:所有者读写,其他只读});console.log('覆盖写入成功');// 2. 追加内容(两种方式)awaitfs.appendFile(filePath,'
这是追加的内容',{encoding:'utf8'});// 或用 writeFile + flag: 'a'// await fs.writeFile(filePath, '
另一种追加方式', { flag: 'a' });}catch(err){console.error('写入失败:',err.message);}}writeFileExample();
3. 复制文件(fs.copyFile)

复制文件,支持原子操作,参数:

  • src:源文件路径;
  • dest:目标文件路径;
  • mode:可选,如fs.constants.COPYFILE_EXCL(目标存在则报错)。
asyncfunctioncopyFileExample(){constsrc=path.resolve(__dirname,'source.txt');constdest=path.resolve(__dirname,'target.txt');try{// 基础复制(目标存在则覆盖)awaitfs.copyFile(src,dest);console.log('文件复制成功');// 原子复制(目标存在则报错)// await fs.copyFile(src, dest, fs.constants.COPYFILE_EXCL);}catch(err){console.error('复制失败:',err.message);}}copyFileExample();
4. 重命名/移动文件(fs.rename)

既可以重命名文件,也可以移动文件(跨目录)。

asyncfunctionrenameFileExample(){constoldPath=path.resolve(__dirname,'old-name.txt');constnewPath=path.resolve(__dirname,'new-name.txt');// 移动到子目录constmovePath=path.resolve(__dirname,'subdir/new-name.txt');try{// 1. 重命名awaitfs.rename(oldPath,newPath);console.log('重命名成功');// 2. 移动(需确保子目录存在)awaitfs.mkdir(path.dirname(movePath),{recursive:true});awaitfs.rename(newPath,movePath);console.log('移动文件成功');}catch(err){console.error('重命名/移动失败:',err.message);}}renameFileExample();
5. 删除文件(fs.unlink / fs.rm)
  • fs.unlink:传统删除文件方法;
  • fs.rm(Node.js 14+):更通用,支持文件/目录,推荐使用。
asyncfunctiondeleteFileExample(){constfilePath=path.resolve(__dirname,'to-delete.txt');try{// 推荐:fs.rm(force: true 避免文件不存在时报错)awaitfs.rm(filePath,{force:true});console.log('文件删除成功');// 传统方式:fs.unlink// await fs.unlink(filePath);}catch(err){console.error('删除失败:',err.message);}}deleteFileExample();
6. 获取文件信息(fs.stat / fs.lstat)
  • fs.stat:获取文件/目录信息;
  • fs.lstat:区分符号链接(返回链接本身信息,而非目标文件)。
asyncfunctiongetFileStat(){constfilePath=path.resolve(__dirname,'example.txt');try{conststats=awaitfs.stat(filePath);console.log('文件信息:',{isFile:stats.isFile(),// 是否是文件isDirectory:stats.isDirectory(),// 是否是目录size:stats.size,// 大小(字节)birthtime:stats.birthtime,// 创建时间mtime:stats.mtime// 修改时间});}catch(err){console.error('获取文件信息失败:',err.message);}}getFileStat();

(二)目录操作

1. 创建目录(fs.mkdir)

支持创建多级目录(recursive: true)。

asyncfunctioncreateDirExample(){// 多级目录constdirPath=path.resolve(__dirname,'new-dir/sub-dir/child-dir');try{awaitfs.mkdir(dirPath,{recursive:true,// 自动创建不存在的父目录mode:0o755// 目录权限:所有者读写执行,其他读执行});console.log('多级目录创建成功');}catch(err){console.error('创建目录失败:',err.message);}}createDirExample();
2. 读取目录(fs.readdir)

读取目录下的文件/子目录,withFileTypes: true可获取文件类型信息。

asyncfunctionreadDirExample(){constdirPath=path.resolve(__dirname,'new-dir');try{// withFileTypes: true 返回 Dirent 对象(包含类型信息)constdirents=awaitfs.readdir(dirPath,{withFileTypes:true});dirents.forEach(dirent=>{consttype=dirent.isFile()?'文件':dirent.isDirectory()?'目录':'其他';console.log(`名称:${dirent.name},类型:${type}`);});}catch(err){console.error('读取目录失败:',err.message);}}readDirExample();
3. 删除目录(fs.rmdir / fs.rm)
  • fs.rmdir:传统删除目录(需空目录,Node.js 12+ 支持recursive: true删除非空);
  • fs.rm(Node.js 14+):推荐,支持递归删除非空目录。
asyncfunctiondeleteDirExample(){constdirPath=path.resolve(__dirname,'new-dir');try{// 推荐:fs.rm 递归删除(force: true 避免目录不存在时报错)awaitfs.rm(dirPath,{recursive:true,force:true});console.log('目录删除成功');// 传统方式:fs.rmdir(需 recursive: true)// await fs.rmdir(dirPath, { recursive: true });}catch(err){console.error('删除目录失败:',err.message);}}deleteDirExample();

(三)其他常用方法

1. 检查文件可访问性(fs.access)

验证文件/目录的权限(读/写/执行)或是否存在。

asyncfunctioncheckAccessExample(){constfilePath=path.resolve(__dirname,'example.txt');try{// 检查是否存在(fs.constants.F_OK)awaitfs.access(filePath,fs.constants.F_OK);console.log('文件存在');// 检查是否可读(fs.constants.R_OK)awaitfs.access(filePath,fs.constants.R_OK);console.log('文件可读');// 检查是否可写(fs.constants.W_OK)awaitfs.access(filePath,fs.constants.W_OK);console.log('文件可写');}catch(err){console.error('访问检查失败:',err.message);}}checkAccessExample();
2. 符号链接操作(fs.symlink / fs.readlink)
asyncfunctionsymlinkExample(){consttarget=path.resolve(__dirname,'example.txt');// 目标文件constlinkPath=path.resolve(__dirname,'example-link.txt');// 链接文件try{// 创建符号链接awaitfs.symlink(target,linkPath);console.log('符号链接创建成功');// 读取链接指向的路径constrealPath=awaitfs.readlink(linkPath);console.log('链接指向:',realPath);}catch(err){console.error('符号链接操作失败:',err.message);}}symlinkExample();

三、错误处理

fs.promises所有方法返回的 Promise 失败时会抛出错误,需用try/catch捕获,常见错误码:

错误码含义
ENOENT文件/目录不存在
EACCES权限不足
EEXIST文件/目录已存在(原子操作时)
EPERM操作不被系统允许
EISDIR操作对象是目录(但方法要求文件)

示例:针对性错误处理

asyncfunctionerrorHandlingExample(){constfilePath=path.resolve(__dirname,'non-existent.txt');try{awaitfs.readFile(filePath,'utf8');}catch(err){switch(err.code){case'ENOENT':console.error('错误:文件不存在');break;case'EACCES':console.error('错误:无读取权限');break;default:console.error('未知错误:',err.message);}}}errorHandlingExample();

四、关键注意事项

1. ESM 中 __dirname/__filename 替代

ESM 中没有__dirname/__filename,需手动实现:

import{fileURLToPath}from'url';import{dirname}from'path';const__filename=fileURLToPath(import.meta.url);// 当前文件路径const__dirname=dirname(__filename);// 当前文件目录

2. 大文件处理

fs.readFile/fs.writeFile会将整个文件加载到内存,大文件(>100MB)推荐使用流

import{createReadStream,createWriteStream}from'fs';import{pipeline}from'stream/promises';// 流的 Promise 化 APIasyncfunctionstreamLargeFile(){constsrc=path.resolve(__dirname,'large-file.txt');constdest=path.resolve(__dirname,'copy-large-file.txt');try{// 流式复制大文件awaitpipeline(createReadStream(src),createWriteStream(dest));console.log('大文件复制成功');}catch(err){console.error('大文件处理失败:',err.message);}}streamLargeFile();

3. 批量操作优化

批量处理文件时,用Promise.all并行执行(注意系统文件描述符限制):

asyncfunctionbatchReadFiles(){constfiles=['file1.txt','file2.txt','file3.txt'].map(f=>path.resolve(__dirname,f));try{// 并行读取(失败时捕获单个错误,不阻塞整体)constresults=awaitPromise.all(files.map(file=>fs.readFile(file,'utf8').catch(err=>({file,error:err.message}))));results.forEach((res,idx)=>{if(res.error){console.error(`读取${files[idx]}失败:`,res.error);}else{console.log(`读取${files[idx]}成功:`,res.substring(0,50)+'...');}});}catch(err){console.error('批量操作异常:',err.message);}}batchReadFiles();

4. 原子操作

使用flag参数实现原子写入(避免并发覆盖):

  • wx:写入文件,若文件已存在则失败;
  • ax:追加内容,若文件不存在则失败。
asyncfunctionatomicWrite(){constfilePath=path.resolve(__dirname,'atomic.txt');try{awaitfs.writeFile(filePath,'原子写入内容',{flag:'wx'});console.log('原子写入成功');}catch(err){if(err.code==='EEXIST'){console.error('文件已存在,原子写入失败(避免覆盖)');}}}atomicWrite();

五、总结

fs.promises是 Node.js 处理文件系统的现代方案,核心优势:

  1. 摆脱回调地狱,代码更易读、易维护;
  2. 适配async/await,错误处理更清晰;
  3. API 语义化,与传统fs方法一一对应,学习成本低。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

建设部网站南京网站建设

macOS视频播放器IINA完全掌握:从入门到精通的高效使用指南【免费下载链接】iina项目地址: https://gitcode.com/gh_mirrors/iin/iina作为ma

2026/06/30 10:47:22

无锡网站建设郴州网站建设

暗黑破坏神2存档编辑器:新手快速上手指南【免费下载链接】d2s-editor项目地址: https://gitcode.com/gh_mirrors/d2/d2s-editor作为一名暗

2026/06/30 12:21:30

seo网站建设建设行业网站

网络术语与Linux内核构建全解析1. 重要网络术语介绍在网络技术领域,有许多关键的术语和概念,它们构成了网络通信和数据处理的基础。下面将对一些重要的网络术语进行详细介绍。1.1 TCAM - 三元内

2026/06/30 10:59:23

网站建设 公司网站建设计

React Native MMKV架构深度解析:突破性性能背后的技术实现【免费下载链接】react-native-mmkv⚡️ The fastest key/value storage

2026/06/30 11:34:56

肇庆网站建设孝感网站建设

如何用STM32的HAL库打造一个“会自己干活”的ADC扫描系统?你有没有遇到过这种情况:想读几个传感器的数据,结果主循环里塞满了HAL_ADC_Start(

2026/06/30 11:21:55

舟山网站建设广西网站建设公司

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等

2026/06/30 13:48:37

荆州网站建设移动网站建设

对比科大讯飞API:自建VoxCPM-1.5-TTS-WEB-UI成本节省90%以上在智能语音技术日益普及的今天,越来越多企业开始部署文本转语音(TTS&#x

2026/06/30 10:41:51

西安网站建设荆门网站建设

还在为无法随时随地阅读番茄小说而烦恼吗?这款番茄小说下载工具为你提供了完美的批量下载方案,让你轻松建立个人数字书库,享受真正的阅读自由!无论你是

2026/06/30 12:54:03

莆田网站建设行业网站建设

第一章:Open-AutoGLM健身卡预约实战指南概述本指南旨在帮助开发者与技术爱好者掌握如何使用 Open-AutoGLM 框架实现自动化健身卡预约任务。该框架结合了自然语言理解与自动

2026/06/30 13:06:34

山东省建设厅网站建设学校网站

Audacity音频编辑神器:免费专业工具完整使用指南【免费下载链接】audacityAudio Editor项目地址: https://gitcode.com/GitHub_Trend

2026/06/30 12:46:03