2025/12/25 3:56:11
网站建设
项目流程
电商网站有哪些功能模块,绵阳市建设工程质监站网站,做网站需要找人优化吗,拓者设计官网网页版fs.promises 是 Node.js fs 模块提供的Promise 化文件系统 API#xff0c;替代了传统的回调式 fs 方法#xff0c;天然适配 async/await 语法#xff0c;是现代 Node.js 开发中处理文件系统的首选方式。
一、核心基础
1. 兼容性
Node.js v10.0.0 起#xff0c;fs.promis…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 模块importfsfromfs/promises;// 配合路径处理ESM 内置模块importpathfrompath;兼容更低版本Node.js 10import{promisesasfs}fromfs;importpathfrompath;二、核心方法 代码示例一文件基础操作1. 读取文件fs.readFile读取文件内容支持文本/二进制格式参数说明path文件路径推荐用path.resolve处理options可选包含encoding编码如utf8、flag操作模式如r只读。示例1读取文本文件asyncfunctionreadTextFile(){// 绝对路径避免相对路径陷阱constfilePathpath.resolve(__dirname,example.txt);try{constcontentawaitfs.readFile(filePath,{encoding:utf8,// 文本编码省略则返回 Bufferflag:r// 只读模式默认});console.log(文件内容\n,content);}catch(err){console.error(读取失败,err.message);}}readTextFile();示例2读取二进制文件图片/视频asyncfunctionreadBinaryFile(){constimgPathpath.resolve(__dirname,image.png);try{// 不指定 encoding返回 Bufferconstbufferawaitfs.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/Uint8Arrayoptions可选包含encoding、flagw覆盖、a追加、wx原子写入文件存在则失败、mode文件权限如0o644。示例写入/追加文件asyncfunctionwriteFileExample(){constfilePathpath.resolve(__dirname,output.txt);constcontentHello fs.promises! 当前时间${newDate().toISOString()};try{// 1. 覆盖写入默认 flag: wawaitfs.writeFile(filePath,content,{encoding:utf8,mode:0o644// 权限所有者读写其他只读});console.log(覆盖写入成功);// 2. 追加内容两种方式awaitfs.appendFile(filePath,\n这是追加的内容,{encoding:utf8});// 或用 writeFile flag: a// await fs.writeFile(filePath, \n另一种追加方式, { flag: a });}catch(err){console.error(写入失败,err.message);}}writeFileExample();3. 复制文件fs.copyFile复制文件支持原子操作参数src源文件路径dest目标文件路径mode可选如fs.constants.COPYFILE_EXCL目标存在则报错。asyncfunctioncopyFileExample(){constsrcpath.resolve(__dirname,source.txt);constdestpath.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(){constoldPathpath.resolve(__dirname,old-name.txt);constnewPathpath.resolve(__dirname,new-name.txt);// 移动到子目录constmovePathpath.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.rmfs.unlink传统删除文件方法fs.rmNode.js 14更通用支持文件/目录推荐使用。asyncfunctiondeleteFileExample(){constfilePathpath.resolve(__dirname,to-delete.txt);try{// 推荐fs.rmforce: 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.lstatfs.stat获取文件/目录信息fs.lstat区分符号链接返回链接本身信息而非目标文件。asyncfunctiongetFileStat(){constfilePathpath.resolve(__dirname,example.txt);try{conststatsawaitfs.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(){// 多级目录constdirPathpath.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(){constdirPathpath.resolve(__dirname,new-dir);try{// withFileTypes: true 返回 Dirent 对象包含类型信息constdirentsawaitfs.readdir(dirPath,{withFileTypes:true});dirents.forEach(dirent{consttypedirent.isFile()?文件:dirent.isDirectory()?目录:其他;console.log(名称${dirent.name}类型${type});});}catch(err){console.error(读取目录失败,err.message);}}readDirExample();3. 删除目录fs.rmdir / fs.rmfs.rmdir传统删除目录需空目录Node.js 12 支持recursive: true删除非空fs.rmNode.js 14推荐支持递归删除非空目录。asyncfunctiondeleteDirExample(){constdirPathpath.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(){constfilePathpath.resolve(__dirname,example.txt);try{// 检查是否存在fs.constants.F_OKawaitfs.access(filePath,fs.constants.F_OK);console.log(文件存在);// 检查是否可读fs.constants.R_OKawaitfs.access(filePath,fs.constants.R_OK);console.log(文件可读);// 检查是否可写fs.constants.W_OKawaitfs.access(filePath,fs.constants.W_OK);console.log(文件可写);}catch(err){console.error(访问检查失败,err.message);}}checkAccessExample();2. 符号链接操作fs.symlink / fs.readlinkasyncfunctionsymlinkExample(){consttargetpath.resolve(__dirname,example.txt);// 目标文件constlinkPathpath.resolve(__dirname,example-link.txt);// 链接文件try{// 创建符号链接awaitfs.symlink(target,linkPath);console.log(符号链接创建成功);// 读取链接指向的路径constrealPathawaitfs.readlink(linkPath);console.log(链接指向,realPath);}catch(err){console.error(符号链接操作失败,err.message);}}symlinkExample();三、错误处理fs.promises所有方法返回的 Promise 失败时会抛出错误需用try/catch捕获常见错误码错误码含义ENOENT文件/目录不存在EACCES权限不足EEXIST文件/目录已存在原子操作时EPERM操作不被系统允许EISDIR操作对象是目录但方法要求文件示例针对性错误处理asyncfunctionerrorHandlingExample(){constfilePathpath.resolve(__dirname,non-existent.txt);try{awaitfs.readFile(filePath,utf8);}catch(err){switch(err.code){caseENOENT:console.error(错误文件不存在);break;caseEACCES:console.error(错误无读取权限);break;default:console.error(未知错误,err.message);}}}errorHandlingExample();四、关键注意事项1. ESM 中 __dirname/__filename 替代ESM 中没有__dirname/__filename需手动实现import{fileURLToPath}fromurl;import{dirname}frompath;const__filenamefileURLToPath(import.meta.url);// 当前文件路径const__dirnamedirname(__filename);// 当前文件目录2. 大文件处理fs.readFile/fs.writeFile会将整个文件加载到内存大文件100MB推荐使用流import{createReadStream,createWriteStream}fromfs;import{pipeline}fromstream/promises;// 流的 Promise 化 APIasyncfunctionstreamLargeFile(){constsrcpath.resolve(__dirname,large-file.txt);constdestpath.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(fpath.resolve(__dirname,f));try{// 并行读取失败时捕获单个错误不阻塞整体constresultsawaitPromise.all(files.map(filefs.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(){constfilePathpath.resolve(__dirname,atomic.txt);try{awaitfs.writeFile(filePath,原子写入内容,{flag:wx});console.log(原子写入成功);}catch(err){if(err.codeEEXIST){console.error(文件已存在原子写入失败避免覆盖);}}}atomicWrite();五、总结fs.promises是 Node.js 处理文件系统的现代方案核心优势摆脱回调地狱代码更易读、易维护适配async/await错误处理更清晰API 语义化与传统fs方法一一对应学习成本低。