[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"knowledge-\u002Fapi\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnodejs\u002Fcore\u002Ffs":3,"knowledge-related-\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnodejs\u002Fcore\u002Ffs":2532,"knowledge-series-\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnodejs\u002Fcore\u002Ffs":2558},{"source":4,"connector":5,"page":6},"sqlite","better-sqlite3",{"path":7,"title":8,"description":9,"category":10,"tags":11,"date":14,"pinned":15,"draft":15,"body":16,"seo":2528,"stem":2529,"id":2530,"extension":2531},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnodejs\u002Fcore\u002Ffs","文件系统","Node.js 的 fs 模块提供了与文件系统交互的 API，几乎涵盖了所有标准文件操作。它支持三种风格的 API：同步、回调式异步 和 Promise 式异步。下面详细介绍这些 API 的选择策略、流式读写、文件监视以及常用操作。","技能小册",[12,13],"nodejs","fs","2026-06-04",false,{"type":17,"value":18,"toc":2517},"minimark",[19,22,27,48,53,68,73,95,179,183,199,301,309,329,440,445,474,485,492,498,735,741,886,894,897,1041,1049,1063,1158,1168,1172,1183,1190,1388,1420,1427,1565,1576,1590,1594,1598,1633,1747,1751,1823,1827,1917,1924,1930,2013,2024,2028,2036,2123,2131,2183,2202,2206,2247,2250,2447,2452,2483,2486,2513],[20,21,8],"h1",{"id":8},[23,24,26],"h2",{"id":25},"nodejs-文件系统fs模块详解","Node.js 文件系统（fs）模块详解",[28,29,30,31,34,35,39,40,43,44,47],"p",{},"Node.js 的 ",[32,33,13],"code",{}," 模块提供了与文件系统交互的 API，几乎涵盖了所有标准文件操作。它支持三种风格的 API：",[36,37,38],"strong",{},"同步","、",[36,41,42],{},"回调式异步"," 和 ",[36,45,46],{},"Promise"," 式异步。下面详细介绍这些 API 的选择策略、流式读写、文件监视以及常用操作。",[49,50,52],"h3",{"id":51},"一同步-异步-promise-api-选择","一、同步 \u002F 异步 \u002F Promise API 选择",[28,54,55,57,58,39,61,39,64,67],{},[32,56,13],{}," 模块的每个操作都有三种形态，例如读取文件：",[32,59,60],{},"fs.readFileSync()",[32,62,63],{},"fs.readFile()",[32,65,66],{},"fs.promises.readFile()","。",[69,70,72],"h4",{"id":71},"_1-同步-apisync","1. 同步 API（Sync）",[74,75,76,83,89],"ul",{},[77,78,79,82],"li",{},[36,80,81],{},"特点","：阻塞事件循环，直到操作完成。易于编写和理解，但没有并发能力。",[77,84,85,88],{},[36,86,87],{},"适用场景","：初始化加载配置、脚本工具、CLI 程序等不需要高并发的场景。",[77,90,91,94],{},[36,92,93],{},"示例","：",[96,97,102],"pre",{"className":98,"code":99,"language":100,"meta":101,"style":101},"language-js shiki shiki-themes material-theme-lighter github-light github-dark","const data = fs.readFileSync(\".\u002Ffile.txt\", \"utf8\");\nconsole.log(data);\n","js","",[32,103,104,163],{"__ignoreMap":101},[105,106,109,113,117,121,125,129,133,136,140,144,146,149,152,155,157,160],"span",{"class":107,"line":108},"line",1,[105,110,112],{"class":111},"sbsja","const",[105,114,116],{"class":115},"s_hVV"," data",[105,118,120],{"class":119},"smGrS"," =",[105,122,124],{"class":123},"su5hD"," fs",[105,126,128],{"class":127},"sP7_E",".",[105,130,132],{"class":131},"sGLFI","readFileSync",[105,134,135],{"class":123},"(",[105,137,139],{"class":138},"sjJ54","\"",[105,141,143],{"class":142},"s_sjI",".\u002Ffile.txt",[105,145,139],{"class":138},[105,147,148],{"class":127},",",[105,150,151],{"class":138}," \"",[105,153,154],{"class":142},"utf8",[105,156,139],{"class":138},[105,158,159],{"class":123},")",[105,161,162],{"class":127},";\n",[105,164,166,169,171,174,177],{"class":107,"line":165},2,[105,167,168],{"class":123},"console",[105,170,128],{"class":127},[105,172,173],{"class":131},"log",[105,175,176],{"class":123},"(data)",[105,178,162],{"class":127},[69,180,182],{"id":181},"_2-回调式异步-api","2. 回调式异步 API",[74,184,185,190,195],{},[77,186,187,189],{},[36,188,81],{},"：非阻塞，利用 Node.js 事件循环，需要提供回调函数处理结果。是 Node.js 传统风格。",[77,191,192,194],{},[36,193,87],{},"：兼容旧代码，或需要精细控制错误处理时。",[77,196,197,94],{},[36,198,93],{},[96,200,202],{"className":98,"code":201,"language":100,"meta":101,"style":101},"fs.readFile(\".\u002Ffile.txt\", \"utf8\", (err, data) => {\n    if (err) throw err;\n    console.log(data);\n});\n",[32,203,204,250,272,291],{"__ignoreMap":101},[105,205,206,208,210,213,215,217,219,221,223,225,227,229,231,234,238,240,242,244,247],{"class":107,"line":108},[105,207,13],{"class":123},[105,209,128],{"class":127},[105,211,212],{"class":131},"readFile",[105,214,135],{"class":123},[105,216,139],{"class":138},[105,218,143],{"class":142},[105,220,139],{"class":138},[105,222,148],{"class":127},[105,224,151],{"class":138},[105,226,154],{"class":142},[105,228,139],{"class":138},[105,230,148],{"class":127},[105,232,233],{"class":127}," (",[105,235,237],{"class":236},"s99_P","err",[105,239,148],{"class":127},[105,241,116],{"class":236},[105,243,159],{"class":127},[105,245,246],{"class":111}," =>",[105,248,249],{"class":127}," {\n",[105,251,252,256,259,261,264,267,270],{"class":107,"line":165},[105,253,255],{"class":254},"sVHd0","    if",[105,257,233],{"class":258},"skxfh",[105,260,237],{"class":123},[105,262,263],{"class":258},") ",[105,265,266],{"class":254},"throw",[105,268,269],{"class":123}," err",[105,271,162],{"class":127},[105,273,275,278,280,282,284,287,289],{"class":107,"line":274},3,[105,276,277],{"class":123},"    console",[105,279,128],{"class":127},[105,281,173],{"class":131},[105,283,135],{"class":258},[105,285,286],{"class":123},"data",[105,288,159],{"class":258},[105,290,162],{"class":127},[105,292,294,297,299],{"class":107,"line":293},4,[105,295,296],{"class":127},"}",[105,298,159],{"class":123},[105,300,162],{"class":127},[69,302,304,305,308],{"id":303},"_3-promise-apifspromises","3. Promise API（",[32,306,307],{},"fs.promises","）",[74,310,311,320,325],{},[77,312,313,315,316,319],{},[36,314,81],{},"：返回 Promise，支持 ",[32,317,318],{},"async\u002Fawait","，使得异步代码更清晰、易于组合。",[77,321,322,324],{},[36,323,87],{},"：现代 Node.js 开发（Node.js 10+ 稳定），推荐优先使用。",[77,326,327,94],{},[36,328,93],{},[96,330,332],{"className":98,"code":331,"language":100,"meta":101,"style":101},"import { promises as fs } from \"fs\";\nasync function read() {\n    const data = await fs.readFile(\".\u002Ffile.txt\", \"utf8\");\n    console.log(data);\n}\n",[32,333,334,364,380,418,434],{"__ignoreMap":101},[105,335,336,339,342,345,348,350,353,356,358,360,362],{"class":107,"line":108},[105,337,338],{"class":254},"import",[105,340,341],{"class":127}," {",[105,343,344],{"class":123}," promises",[105,346,347],{"class":254}," as",[105,349,124],{"class":123},[105,351,352],{"class":127}," }",[105,354,355],{"class":254}," from",[105,357,151],{"class":138},[105,359,13],{"class":142},[105,361,139],{"class":138},[105,363,162],{"class":127},[105,365,366,369,372,375,378],{"class":107,"line":165},[105,367,368],{"class":111},"async",[105,370,371],{"class":111}," function",[105,373,374],{"class":131}," read",[105,376,377],{"class":127},"()",[105,379,249],{"class":127},[105,381,382,385,387,389,392,394,396,398,400,402,404,406,408,410,412,414,416],{"class":107,"line":274},[105,383,384],{"class":111},"    const",[105,386,116],{"class":115},[105,388,120],{"class":119},[105,390,391],{"class":254}," await",[105,393,124],{"class":123},[105,395,128],{"class":127},[105,397,212],{"class":131},[105,399,135],{"class":258},[105,401,139],{"class":138},[105,403,143],{"class":142},[105,405,139],{"class":138},[105,407,148],{"class":127},[105,409,151],{"class":138},[105,411,154],{"class":142},[105,413,139],{"class":138},[105,415,159],{"class":258},[105,417,162],{"class":127},[105,419,420,422,424,426,428,430,432],{"class":107,"line":293},[105,421,277],{"class":123},[105,423,128],{"class":127},[105,425,173],{"class":131},[105,427,135],{"class":258},[105,429,286],{"class":123},[105,431,159],{"class":258},[105,433,162],{"class":127},[105,435,437],{"class":107,"line":436},5,[105,438,439],{"class":127},"}\n",[28,441,442,94],{},[36,443,444],{},"选择建议",[74,446,447,458,464],{},[77,448,449,457],{},[36,450,451,452,454,455],{},"新项目优先使用 ",[32,453,307],{}," + ",[32,456,318],{},"，代码可读性好且不易出错。",[77,459,460,463],{},[36,461,462],{},"工具脚本或初始化","可使用同步 API，简单直接。",[77,465,466,469,470,473],{},[36,467,468],{},"需要高性能且回调嵌套较多的遗留代码","，可考虑用 ",[32,471,472],{},"util.promisify"," 包装回调函数。",[49,475,477,478,481,482,308],{"id":476},"二流式读写createreadstream-createwritestream","二、流式读写（",[32,479,480],{},"createReadStream"," \u002F ",[32,483,484],{},"createWriteStream",[28,486,487,488,491],{},"对于大文件，一次性将整个文件读入内存会导致内存溢出或性能下降。流式读写以",[36,489,490],{},"小块数据","分批处理，适合大文件复制、日志处理、文件上传等场景。",[69,493,495,496,308],{"id":494},"_1-可读流createreadstream","1. 可读流（",[32,497,480],{},[96,499,501],{"className":98,"code":500,"language":100,"meta":101,"style":101},"const readStream = fs.createReadStream(\".\u002FlargeFile.txt\", {\n    encoding: \"utf8\",\n    highWaterMark: 64 * 1024, \u002F\u002F 每次读取 64KB\n});\nreadStream.on(\"data\", chunk => {\n    console.log(`Received ${chunk.length} bytes`);\n});\nreadStream.on(\"end\", () => console.log(\"No more data\"));\nreadStream.on(\"error\", err => console.error(err));\n",[32,502,503,531,548,571,579,606,645,654,700],{"__ignoreMap":101},[105,504,505,507,510,512,514,516,518,520,522,525,527,529],{"class":107,"line":108},[105,506,112],{"class":111},[105,508,509],{"class":115}," readStream",[105,511,120],{"class":119},[105,513,124],{"class":123},[105,515,128],{"class":127},[105,517,480],{"class":131},[105,519,135],{"class":123},[105,521,139],{"class":138},[105,523,524],{"class":142},".\u002FlargeFile.txt",[105,526,139],{"class":138},[105,528,148],{"class":127},[105,530,249],{"class":127},[105,532,533,536,539,541,543,545],{"class":107,"line":165},[105,534,535],{"class":258},"    encoding",[105,537,538],{"class":127},":",[105,540,151],{"class":138},[105,542,154],{"class":142},[105,544,139],{"class":138},[105,546,547],{"class":127},",\n",[105,549,550,553,555,559,562,565,567],{"class":107,"line":274},[105,551,552],{"class":258},"    highWaterMark",[105,554,538],{"class":127},[105,556,558],{"class":557},"srdBf"," 64",[105,560,561],{"class":119}," *",[105,563,564],{"class":557}," 1024",[105,566,148],{"class":127},[105,568,570],{"class":569},"sutJx"," \u002F\u002F 每次读取 64KB\n",[105,572,573,575,577],{"class":107,"line":293},[105,574,296],{"class":127},[105,576,159],{"class":123},[105,578,162],{"class":127},[105,580,581,584,586,589,591,593,595,597,599,602,604],{"class":107,"line":436},[105,582,583],{"class":123},"readStream",[105,585,128],{"class":127},[105,587,588],{"class":131},"on",[105,590,135],{"class":123},[105,592,139],{"class":138},[105,594,286],{"class":142},[105,596,139],{"class":138},[105,598,148],{"class":127},[105,600,601],{"class":236}," chunk",[105,603,246],{"class":111},[105,605,249],{"class":127},[105,607,609,611,613,615,617,620,623,626,629,631,634,636,639,641,643],{"class":107,"line":608},6,[105,610,277],{"class":123},[105,612,128],{"class":127},[105,614,173],{"class":131},[105,616,135],{"class":258},[105,618,619],{"class":138},"`",[105,621,622],{"class":142},"Received ",[105,624,625],{"class":138},"${",[105,627,628],{"class":123},"chunk",[105,630,128],{"class":138},[105,632,633],{"class":115},"length",[105,635,296],{"class":138},[105,637,638],{"class":142}," bytes",[105,640,619],{"class":138},[105,642,159],{"class":258},[105,644,162],{"class":127},[105,646,648,650,652],{"class":107,"line":647},7,[105,649,296],{"class":127},[105,651,159],{"class":123},[105,653,162],{"class":127},[105,655,657,659,661,663,665,667,670,672,674,677,679,682,684,686,688,690,693,695,698],{"class":107,"line":656},8,[105,658,583],{"class":123},[105,660,128],{"class":127},[105,662,588],{"class":131},[105,664,135],{"class":123},[105,666,139],{"class":138},[105,668,669],{"class":142},"end",[105,671,139],{"class":138},[105,673,148],{"class":127},[105,675,676],{"class":127}," ()",[105,678,246],{"class":111},[105,680,681],{"class":123}," console",[105,683,128],{"class":127},[105,685,173],{"class":131},[105,687,135],{"class":123},[105,689,139],{"class":138},[105,691,692],{"class":142},"No more data",[105,694,139],{"class":138},[105,696,697],{"class":123},"))",[105,699,162],{"class":127},[105,701,703,705,707,709,711,713,716,718,720,722,724,726,728,730,733],{"class":107,"line":702},9,[105,704,583],{"class":123},[105,706,128],{"class":127},[105,708,588],{"class":131},[105,710,135],{"class":123},[105,712,139],{"class":138},[105,714,715],{"class":142},"error",[105,717,139],{"class":138},[105,719,148],{"class":127},[105,721,269],{"class":236},[105,723,246],{"class":111},[105,725,681],{"class":123},[105,727,128],{"class":127},[105,729,715],{"class":131},[105,731,732],{"class":123},"(err))",[105,734,162],{"class":127},[69,736,738,739,308],{"id":737},"_2-可写流createwritestream","2. 可写流（",[32,740,484],{},[96,742,744],{"className":98,"code":743,"language":100,"meta":101,"style":101},"const writeStream = fs.createWriteStream(\".\u002Foutput.txt\");\nwriteStream.write(\"Hello\\n\");\nwriteStream.write(\"World\\n\");\nwriteStream.end(\"Done\");\nwriteStream.on(\"finish\", () => console.log(\"Write completed\"));\n",[32,745,746,774,800,823,844],{"__ignoreMap":101},[105,747,748,750,753,755,757,759,761,763,765,768,770,772],{"class":107,"line":108},[105,749,112],{"class":111},[105,751,752],{"class":115}," writeStream",[105,754,120],{"class":119},[105,756,124],{"class":123},[105,758,128],{"class":127},[105,760,484],{"class":131},[105,762,135],{"class":123},[105,764,139],{"class":138},[105,766,767],{"class":142},".\u002Foutput.txt",[105,769,139],{"class":138},[105,771,159],{"class":123},[105,773,162],{"class":127},[105,775,776,779,781,784,786,788,791,794,796,798],{"class":107,"line":165},[105,777,778],{"class":123},"writeStream",[105,780,128],{"class":127},[105,782,783],{"class":131},"write",[105,785,135],{"class":123},[105,787,139],{"class":138},[105,789,790],{"class":142},"Hello",[105,792,793],{"class":115},"\\n",[105,795,139],{"class":138},[105,797,159],{"class":123},[105,799,162],{"class":127},[105,801,802,804,806,808,810,812,815,817,819,821],{"class":107,"line":274},[105,803,778],{"class":123},[105,805,128],{"class":127},[105,807,783],{"class":131},[105,809,135],{"class":123},[105,811,139],{"class":138},[105,813,814],{"class":142},"World",[105,816,793],{"class":115},[105,818,139],{"class":138},[105,820,159],{"class":123},[105,822,162],{"class":127},[105,824,825,827,829,831,833,835,838,840,842],{"class":107,"line":293},[105,826,778],{"class":123},[105,828,128],{"class":127},[105,830,669],{"class":131},[105,832,135],{"class":123},[105,834,139],{"class":138},[105,836,837],{"class":142},"Done",[105,839,139],{"class":138},[105,841,159],{"class":123},[105,843,162],{"class":127},[105,845,846,848,850,852,854,856,859,861,863,865,867,869,871,873,875,877,880,882,884],{"class":107,"line":436},[105,847,778],{"class":123},[105,849,128],{"class":127},[105,851,588],{"class":131},[105,853,135],{"class":123},[105,855,139],{"class":138},[105,857,858],{"class":142},"finish",[105,860,139],{"class":138},[105,862,148],{"class":127},[105,864,676],{"class":127},[105,866,246],{"class":111},[105,868,681],{"class":123},[105,870,128],{"class":127},[105,872,173],{"class":131},[105,874,135],{"class":123},[105,876,139],{"class":138},[105,878,879],{"class":142},"Write completed",[105,881,139],{"class":138},[105,883,697],{"class":123},[105,885,162],{"class":127},[69,887,889,890,893],{"id":888},"_3-管道pipe复制文件","3. 管道（",[32,891,892],{},"pipe","）复制文件",[28,895,896],{},"将可读流直接导向可写流，实现高效复制：",[96,898,900],{"className":98,"code":899,"language":100,"meta":101,"style":101},"const src = fs.createReadStream(\".\u002Fsource.txt\");\nconst dest = fs.createWriteStream(\".\u002Fdest.txt\");\nsrc.pipe(dest);\nsrc.on(\"error\", console.error);\ndest.on(\"finish\", () => console.log(\"Copy finished\"));\n",[32,901,902,930,958,972,999],{"__ignoreMap":101},[105,903,904,906,909,911,913,915,917,919,921,924,926,928],{"class":107,"line":108},[105,905,112],{"class":111},[105,907,908],{"class":115}," src",[105,910,120],{"class":119},[105,912,124],{"class":123},[105,914,128],{"class":127},[105,916,480],{"class":131},[105,918,135],{"class":123},[105,920,139],{"class":138},[105,922,923],{"class":142},".\u002Fsource.txt",[105,925,139],{"class":138},[105,927,159],{"class":123},[105,929,162],{"class":127},[105,931,932,934,937,939,941,943,945,947,949,952,954,956],{"class":107,"line":165},[105,933,112],{"class":111},[105,935,936],{"class":115}," dest",[105,938,120],{"class":119},[105,940,124],{"class":123},[105,942,128],{"class":127},[105,944,484],{"class":131},[105,946,135],{"class":123},[105,948,139],{"class":138},[105,950,951],{"class":142},".\u002Fdest.txt",[105,953,139],{"class":138},[105,955,159],{"class":123},[105,957,162],{"class":127},[105,959,960,963,965,967,970],{"class":107,"line":274},[105,961,962],{"class":123},"src",[105,964,128],{"class":127},[105,966,892],{"class":131},[105,968,969],{"class":123},"(dest)",[105,971,162],{"class":127},[105,973,974,976,978,980,982,984,986,988,990,992,994,997],{"class":107,"line":293},[105,975,962],{"class":123},[105,977,128],{"class":127},[105,979,588],{"class":131},[105,981,135],{"class":123},[105,983,139],{"class":138},[105,985,715],{"class":142},[105,987,139],{"class":138},[105,989,148],{"class":127},[105,991,681],{"class":123},[105,993,128],{"class":127},[105,995,996],{"class":123},"error)",[105,998,162],{"class":127},[105,1000,1001,1004,1006,1008,1010,1012,1014,1016,1018,1020,1022,1024,1026,1028,1030,1032,1035,1037,1039],{"class":107,"line":436},[105,1002,1003],{"class":123},"dest",[105,1005,128],{"class":127},[105,1007,588],{"class":131},[105,1009,135],{"class":123},[105,1011,139],{"class":138},[105,1013,858],{"class":142},[105,1015,139],{"class":138},[105,1017,148],{"class":127},[105,1019,676],{"class":127},[105,1021,246],{"class":111},[105,1023,681],{"class":123},[105,1025,128],{"class":127},[105,1027,173],{"class":131},[105,1029,135],{"class":123},[105,1031,139],{"class":138},[105,1033,1034],{"class":142},"Copy finished",[105,1036,139],{"class":138},[105,1038,697],{"class":123},[105,1040,162],{"class":127},[69,1042,1044,1045,1048],{"id":1043},"_4-高级pipeline-方法处理错误自动清理","4. 高级：",[32,1046,1047],{},"pipeline"," 方法（处理错误自动清理）",[28,1050,1051,1052,1055,1056,1058,1059,1062],{},"推荐使用 ",[32,1053,1054],{},"stream.pipeline"," 或 ",[32,1057,307],{}," 的 ",[32,1060,1061],{},"copyFile"," 对于简单复制更简单。",[96,1064,1066],{"className":98,"code":1065,"language":100,"meta":101,"style":101},"const { pipeline } = require(\"stream\");\nconst { promisify } = require(\"util\");\nconst pipelineAsync = promisify(pipeline);\nawait pipelineAsync(src, dest);\n",[32,1067,1068,1097,1125,1141],{"__ignoreMap":101},[105,1069,1070,1072,1074,1077,1079,1081,1084,1086,1088,1091,1093,1095],{"class":107,"line":108},[105,1071,112],{"class":111},[105,1073,341],{"class":127},[105,1075,1076],{"class":115}," pipeline",[105,1078,352],{"class":127},[105,1080,120],{"class":119},[105,1082,1083],{"class":131}," require",[105,1085,135],{"class":123},[105,1087,139],{"class":138},[105,1089,1090],{"class":142},"stream",[105,1092,139],{"class":138},[105,1094,159],{"class":123},[105,1096,162],{"class":127},[105,1098,1099,1101,1103,1106,1108,1110,1112,1114,1116,1119,1121,1123],{"class":107,"line":165},[105,1100,112],{"class":111},[105,1102,341],{"class":127},[105,1104,1105],{"class":115}," promisify",[105,1107,352],{"class":127},[105,1109,120],{"class":119},[105,1111,1083],{"class":131},[105,1113,135],{"class":123},[105,1115,139],{"class":138},[105,1117,1118],{"class":142},"util",[105,1120,139],{"class":138},[105,1122,159],{"class":123},[105,1124,162],{"class":127},[105,1126,1127,1129,1132,1134,1136,1139],{"class":107,"line":274},[105,1128,112],{"class":111},[105,1130,1131],{"class":115}," pipelineAsync",[105,1133,120],{"class":119},[105,1135,1105],{"class":131},[105,1137,1138],{"class":123},"(pipeline)",[105,1140,162],{"class":127},[105,1142,1143,1146,1148,1151,1153,1156],{"class":107,"line":293},[105,1144,1145],{"class":254},"await",[105,1147,1131],{"class":131},[105,1149,1150],{"class":123},"(src",[105,1152,148],{"class":127},[105,1154,1155],{"class":123}," dest)",[105,1157,162],{"class":127},[28,1159,1160,1163,1164,1167],{},[36,1161,1162],{},"注意","：对于普通文件复制，",[32,1165,1166],{},"fs.copyFile"," 比手动流更高效，但流式读写适用于需要处理数据（如压缩、加密）的场景。",[49,1169,1171],{"id":1170},"三监视文件变化","三、监视文件变化",[28,1173,1174,1175,1178,1179,1182],{},"Node.js 提供了两种监视文件\u002F目录变化的方法：",[32,1176,1177],{},"fs.watch","（推荐）和 ",[32,1180,1181],{},"fs.watchFile","（轮询）。",[69,1184,1186,1187,1189],{"id":1185},"_1-fswatch基于操作系统事件效率高","1. ",[32,1188,1177],{},"（基于操作系统事件，效率高）",[96,1191,1193],{"className":98,"code":1192,"language":100,"meta":101,"style":101},"const watcher = fs.watch(\n    \".\u002FsomeDir\",\n    { recursive: true },\n    (eventType, filename) => {\n        console.log(`事件类型: ${eventType}`);\n        if (filename) console.log(`文件名: ${filename}`);\n    }\n);\nwatcher.on(\"error\", err => console.error(err));\n\u002F\u002F 停止监视\nwatcher.close();\n",[32,1194,1195,1214,1226,1243,1262,1289,1324,1329,1335,1368,1374],{"__ignoreMap":101},[105,1196,1197,1199,1202,1204,1206,1208,1211],{"class":107,"line":108},[105,1198,112],{"class":111},[105,1200,1201],{"class":115}," watcher",[105,1203,120],{"class":119},[105,1205,124],{"class":123},[105,1207,128],{"class":127},[105,1209,1210],{"class":131},"watch",[105,1212,1213],{"class":123},"(\n",[105,1215,1216,1219,1222,1224],{"class":107,"line":165},[105,1217,1218],{"class":138},"    \"",[105,1220,1221],{"class":142},".\u002FsomeDir",[105,1223,139],{"class":138},[105,1225,547],{"class":127},[105,1227,1228,1231,1234,1236,1240],{"class":107,"line":274},[105,1229,1230],{"class":127},"    {",[105,1232,1233],{"class":258}," recursive",[105,1235,538],{"class":127},[105,1237,1239],{"class":1238},"syTEX"," true",[105,1241,1242],{"class":127}," },\n",[105,1244,1245,1248,1251,1253,1256,1258,1260],{"class":107,"line":293},[105,1246,1247],{"class":127},"    (",[105,1249,1250],{"class":236},"eventType",[105,1252,148],{"class":127},[105,1254,1255],{"class":236}," filename",[105,1257,159],{"class":127},[105,1259,246],{"class":111},[105,1261,249],{"class":127},[105,1263,1264,1267,1269,1271,1273,1275,1278,1280,1282,1285,1287],{"class":107,"line":436},[105,1265,1266],{"class":123},"        console",[105,1268,128],{"class":127},[105,1270,173],{"class":131},[105,1272,135],{"class":258},[105,1274,619],{"class":138},[105,1276,1277],{"class":142},"事件类型: ",[105,1279,625],{"class":138},[105,1281,1250],{"class":123},[105,1283,1284],{"class":138},"}`",[105,1286,159],{"class":258},[105,1288,162],{"class":127},[105,1290,1291,1294,1296,1299,1301,1303,1305,1307,1309,1311,1314,1316,1318,1320,1322],{"class":107,"line":608},[105,1292,1293],{"class":254},"        if",[105,1295,233],{"class":258},[105,1297,1298],{"class":123},"filename",[105,1300,263],{"class":258},[105,1302,168],{"class":123},[105,1304,128],{"class":127},[105,1306,173],{"class":131},[105,1308,135],{"class":258},[105,1310,619],{"class":138},[105,1312,1313],{"class":142},"文件名: ",[105,1315,625],{"class":138},[105,1317,1298],{"class":123},[105,1319,1284],{"class":138},[105,1321,159],{"class":258},[105,1323,162],{"class":127},[105,1325,1326],{"class":107,"line":647},[105,1327,1328],{"class":127},"    }\n",[105,1330,1331,1333],{"class":107,"line":656},[105,1332,159],{"class":123},[105,1334,162],{"class":127},[105,1336,1337,1340,1342,1344,1346,1348,1350,1352,1354,1356,1358,1360,1362,1364,1366],{"class":107,"line":702},[105,1338,1339],{"class":123},"watcher",[105,1341,128],{"class":127},[105,1343,588],{"class":131},[105,1345,135],{"class":123},[105,1347,139],{"class":138},[105,1349,715],{"class":142},[105,1351,139],{"class":138},[105,1353,148],{"class":127},[105,1355,269],{"class":236},[105,1357,246],{"class":111},[105,1359,681],{"class":123},[105,1361,128],{"class":127},[105,1363,715],{"class":131},[105,1365,732],{"class":123},[105,1367,162],{"class":127},[105,1369,1371],{"class":107,"line":1370},10,[105,1372,1373],{"class":569},"\u002F\u002F 停止监视\n",[105,1375,1377,1379,1381,1384,1386],{"class":107,"line":1376},11,[105,1378,1339],{"class":123},[105,1380,128],{"class":127},[105,1382,1383],{"class":131},"close",[105,1385,377],{"class":123},[105,1387,162],{"class":127},[74,1389,1390,1402,1409],{},[77,1391,1392,94,1394,1397,1398,1401],{},[32,1393,1250],{},[32,1395,1396],{},"'rename'","（文件移动\u002F重命名\u002F删除）或 ",[32,1399,1400],{},"'change'","（内容修改）。",[77,1403,1404,1405,1408],{},"参数 ",[32,1406,1407],{},"recursive","：是否监视子目录（需平台支持，macOS 支持，Linux 需额外配置）。",[77,1410,1411,94,1413,1415,1416,1419],{},[36,1412,1162],{},[32,1414,1298],{}," 可能为 ",[32,1417,1418],{},"null","，且某些系统可能不提供完整路径。",[69,1421,1423,1424,1426],{"id":1422},"_2-fswatchfile轮询开销较大","2. ",[32,1425,1181],{},"（轮询，开销较大）",[96,1428,1430],{"className":98,"code":1429,"language":100,"meta":101,"style":101},"fs.watchFile(\".\u002Ffile.txt\", { interval: 1000 }, (curr, prev) => {\n    if (curr.mtime !== prev.mtime) {\n        console.log(\"文件被修改\");\n    }\n});\nfs.unwatchFile(\".\u002Ffile.txt\"); \u002F\u002F 停止监视\n",[32,1431,1432,1480,1507,1528,1532,1540],{"__ignoreMap":101},[105,1433,1434,1436,1438,1441,1443,1445,1447,1449,1451,1453,1456,1458,1461,1464,1466,1469,1471,1474,1476,1478],{"class":107,"line":108},[105,1435,13],{"class":123},[105,1437,128],{"class":127},[105,1439,1440],{"class":131},"watchFile",[105,1442,135],{"class":123},[105,1444,139],{"class":138},[105,1446,143],{"class":142},[105,1448,139],{"class":138},[105,1450,148],{"class":127},[105,1452,341],{"class":127},[105,1454,1455],{"class":258}," interval",[105,1457,538],{"class":127},[105,1459,1460],{"class":557}," 1000",[105,1462,1463],{"class":127}," },",[105,1465,233],{"class":127},[105,1467,1468],{"class":236},"curr",[105,1470,148],{"class":127},[105,1472,1473],{"class":236}," prev",[105,1475,159],{"class":127},[105,1477,246],{"class":111},[105,1479,249],{"class":127},[105,1481,1482,1484,1486,1488,1490,1493,1496,1498,1500,1502,1504],{"class":107,"line":165},[105,1483,255],{"class":254},[105,1485,233],{"class":258},[105,1487,1468],{"class":123},[105,1489,128],{"class":127},[105,1491,1492],{"class":123},"mtime",[105,1494,1495],{"class":119}," !==",[105,1497,1473],{"class":123},[105,1499,128],{"class":127},[105,1501,1492],{"class":123},[105,1503,263],{"class":258},[105,1505,1506],{"class":127},"{\n",[105,1508,1509,1511,1513,1515,1517,1519,1522,1524,1526],{"class":107,"line":274},[105,1510,1266],{"class":123},[105,1512,128],{"class":127},[105,1514,173],{"class":131},[105,1516,135],{"class":258},[105,1518,139],{"class":138},[105,1520,1521],{"class":142},"文件被修改",[105,1523,139],{"class":138},[105,1525,159],{"class":258},[105,1527,162],{"class":127},[105,1529,1530],{"class":107,"line":293},[105,1531,1328],{"class":127},[105,1533,1534,1536,1538],{"class":107,"line":436},[105,1535,296],{"class":127},[105,1537,159],{"class":123},[105,1539,162],{"class":127},[105,1541,1542,1544,1546,1549,1551,1553,1555,1557,1559,1562],{"class":107,"line":608},[105,1543,13],{"class":123},[105,1545,128],{"class":127},[105,1547,1548],{"class":131},"unwatchFile",[105,1550,135],{"class":123},[105,1552,139],{"class":138},[105,1554,143],{"class":142},[105,1556,139],{"class":138},[105,1558,159],{"class":123},[105,1560,1561],{"class":127},";",[105,1563,1564],{"class":569}," \u002F\u002F 停止监视\n",[74,1566,1567,1573],{},[77,1568,1569,1570,1572],{},"使用轮询检查文件状态，适合无法使用 ",[32,1571,1210],{}," 的网络文件系统（NFS）。",[77,1574,1575],{},"性能较差，不推荐在性能敏感场景使用。",[28,1577,1578,1581,1582,1584,1585,1587,1588,67],{},[36,1579,1580],{},"选择","：优先使用 ",[32,1583,1177],{},"，它更高效且实时。如果 ",[32,1586,1210],{}," 不可用或需要跨平台一致性，可回退到 ",[32,1589,1440],{},[49,1591,1593],{"id":1592},"四常用操作","四、常用操作",[69,1595,1597],{"id":1596},"_1-读写文件基本","1. 读写文件（基本）",[74,1599,1600,1608,1616,1625],{},[77,1601,1602,94,1605],{},[36,1603,1604],{},"异步读取",[32,1606,1607],{},"fs.readFile(path, options, callback)",[77,1609,1610,94,1613],{},[36,1611,1612],{},"同步读取",[32,1614,1615],{},"fs.readFileSync(path, options)",[77,1617,1618,94,1621,1624],{},[36,1619,1620],{},"写入文件",[32,1622,1623],{},"fs.writeFile(path, data, options, callback)","（覆盖写入）",[77,1626,1627,94,1630],{},[36,1628,1629],{},"追加写入",[32,1631,1632],{},"fs.appendFile(path, data, callback)",[96,1634,1636],{"className":98,"code":1635,"language":100,"meta":101,"style":101},"\u002F\u002F Promise 示例\nawait fs.writeFile(\".\u002Fhello.txt\", \"Hello Node.js\");\nawait fs.appendFile(\".\u002Fhello.txt\", \"\\nNew line\");\nconst content = await fs.readFile(\".\u002Fhello.txt\", \"utf8\");\n",[32,1637,1638,1643,1676,1710],{"__ignoreMap":101},[105,1639,1640],{"class":107,"line":108},[105,1641,1642],{"class":569},"\u002F\u002F Promise 示例\n",[105,1644,1645,1647,1649,1651,1654,1656,1658,1661,1663,1665,1667,1670,1672,1674],{"class":107,"line":165},[105,1646,1145],{"class":254},[105,1648,124],{"class":123},[105,1650,128],{"class":127},[105,1652,1653],{"class":131},"writeFile",[105,1655,135],{"class":123},[105,1657,139],{"class":138},[105,1659,1660],{"class":142},".\u002Fhello.txt",[105,1662,139],{"class":138},[105,1664,148],{"class":127},[105,1666,151],{"class":138},[105,1668,1669],{"class":142},"Hello Node.js",[105,1671,139],{"class":138},[105,1673,159],{"class":123},[105,1675,162],{"class":127},[105,1677,1678,1680,1682,1684,1687,1689,1691,1693,1695,1697,1699,1701,1704,1706,1708],{"class":107,"line":274},[105,1679,1145],{"class":254},[105,1681,124],{"class":123},[105,1683,128],{"class":127},[105,1685,1686],{"class":131},"appendFile",[105,1688,135],{"class":123},[105,1690,139],{"class":138},[105,1692,1660],{"class":142},[105,1694,139],{"class":138},[105,1696,148],{"class":127},[105,1698,151],{"class":138},[105,1700,793],{"class":115},[105,1702,1703],{"class":142},"New line",[105,1705,139],{"class":138},[105,1707,159],{"class":123},[105,1709,162],{"class":127},[105,1711,1712,1714,1717,1719,1721,1723,1725,1727,1729,1731,1733,1735,1737,1739,1741,1743,1745],{"class":107,"line":293},[105,1713,112],{"class":111},[105,1715,1716],{"class":115}," content",[105,1718,120],{"class":119},[105,1720,391],{"class":254},[105,1722,124],{"class":123},[105,1724,128],{"class":127},[105,1726,212],{"class":131},[105,1728,135],{"class":123},[105,1730,139],{"class":138},[105,1732,1660],{"class":142},[105,1734,139],{"class":138},[105,1736,148],{"class":127},[105,1738,151],{"class":138},[105,1740,154],{"class":142},[105,1742,139],{"class":138},[105,1744,159],{"class":123},[105,1746,162],{"class":127},[69,1748,1750],{"id":1749},"_2-删除文件","2. 删除文件",[96,1752,1754],{"className":98,"code":1753,"language":100,"meta":101,"style":101},"fs.unlink('.\u002FfileToDelete.txt', (err) => { ... });\n\u002F\u002F Promises\nawait fs.unlink('.\u002FfileToDelete.txt');\n",[32,1755,1756,1796,1801],{"__ignoreMap":101},[105,1757,1758,1760,1762,1765,1767,1770,1773,1775,1777,1779,1781,1783,1785,1787,1790,1792,1794],{"class":107,"line":108},[105,1759,13],{"class":123},[105,1761,128],{"class":127},[105,1763,1764],{"class":131},"unlink",[105,1766,135],{"class":123},[105,1768,1769],{"class":138},"'",[105,1771,1772],{"class":142},".\u002FfileToDelete.txt",[105,1774,1769],{"class":138},[105,1776,148],{"class":127},[105,1778,233],{"class":127},[105,1780,237],{"class":236},[105,1782,159],{"class":127},[105,1784,246],{"class":111},[105,1786,341],{"class":127},[105,1788,1789],{"class":119}," ...",[105,1791,352],{"class":127},[105,1793,159],{"class":123},[105,1795,162],{"class":127},[105,1797,1798],{"class":107,"line":165},[105,1799,1800],{"class":569},"\u002F\u002F Promises\n",[105,1802,1803,1805,1807,1809,1811,1813,1815,1817,1819,1821],{"class":107,"line":274},[105,1804,1145],{"class":254},[105,1806,124],{"class":123},[105,1808,128],{"class":127},[105,1810,1764],{"class":131},[105,1812,135],{"class":123},[105,1814,1769],{"class":138},[105,1816,1772],{"class":142},[105,1818,1769],{"class":138},[105,1820,159],{"class":123},[105,1822,162],{"class":127},[69,1824,1826],{"id":1825},"_3-重命名-移动文件","3. 重命名 \u002F 移动文件",[96,1828,1830],{"className":98,"code":1829,"language":100,"meta":101,"style":101},"fs.rename('.\u002FoldName.txt', '.\u002FnewName.txt', (err) => { ... });\n\u002F\u002F 也可用于移动文件到不同目录\nawait fs.rename('.\u002Fdata.txt', '..\u002Fbackup\u002Fdata.txt');\n",[32,1831,1832,1880,1885],{"__ignoreMap":101},[105,1833,1834,1836,1838,1841,1843,1845,1848,1850,1852,1855,1858,1860,1862,1864,1866,1868,1870,1872,1874,1876,1878],{"class":107,"line":108},[105,1835,13],{"class":123},[105,1837,128],{"class":127},[105,1839,1840],{"class":131},"rename",[105,1842,135],{"class":123},[105,1844,1769],{"class":138},[105,1846,1847],{"class":142},".\u002FoldName.txt",[105,1849,1769],{"class":138},[105,1851,148],{"class":127},[105,1853,1854],{"class":138}," '",[105,1856,1857],{"class":142},".\u002FnewName.txt",[105,1859,1769],{"class":138},[105,1861,148],{"class":127},[105,1863,233],{"class":127},[105,1865,237],{"class":236},[105,1867,159],{"class":127},[105,1869,246],{"class":111},[105,1871,341],{"class":127},[105,1873,1789],{"class":119},[105,1875,352],{"class":127},[105,1877,159],{"class":123},[105,1879,162],{"class":127},[105,1881,1882],{"class":107,"line":165},[105,1883,1884],{"class":569},"\u002F\u002F 也可用于移动文件到不同目录\n",[105,1886,1887,1889,1891,1893,1895,1897,1899,1902,1904,1906,1908,1911,1913,1915],{"class":107,"line":274},[105,1888,1145],{"class":254},[105,1890,124],{"class":123},[105,1892,128],{"class":127},[105,1894,1840],{"class":131},[105,1896,135],{"class":123},[105,1898,1769],{"class":138},[105,1900,1901],{"class":142},".\u002Fdata.txt",[105,1903,1769],{"class":138},[105,1905,148],{"class":127},[105,1907,1854],{"class":138},[105,1909,1910],{"class":142},"..\u002Fbackup\u002Fdata.txt",[105,1912,1769],{"class":138},[105,1914,159],{"class":123},[105,1916,162],{"class":127},[69,1918,1920,1921,308],{"id":1919},"_4-权限管理chmod","4. 权限管理（",[32,1922,1923],{},"chmod",[28,1925,1926,1927,1929],{},"修改文件权限（类似 Unix ",[32,1928,1923],{}," 命令）：",[96,1931,1933],{"className":98,"code":1932,"language":100,"meta":101,"style":101},"\u002F\u002F 数字模式：0o644 表示 rw-r--r--\nfs.chmod('.\u002Ffile.txt', 0o644, (err) => { ... });\n\u002F\u002F 符号模式 Node.js 不直接支持，需用数字或相应对照\nawait fs.chmod('.\u002Ffile.txt', 0o755);\n",[32,1934,1935,1940,1981,1986],{"__ignoreMap":101},[105,1936,1937],{"class":107,"line":108},[105,1938,1939],{"class":569},"\u002F\u002F 数字模式：0o644 表示 rw-r--r--\n",[105,1941,1942,1944,1946,1948,1950,1952,1954,1956,1958,1961,1963,1965,1967,1969,1971,1973,1975,1977,1979],{"class":107,"line":165},[105,1943,13],{"class":123},[105,1945,128],{"class":127},[105,1947,1923],{"class":131},[105,1949,135],{"class":123},[105,1951,1769],{"class":138},[105,1953,143],{"class":142},[105,1955,1769],{"class":138},[105,1957,148],{"class":127},[105,1959,1960],{"class":557}," 0o644",[105,1962,148],{"class":127},[105,1964,233],{"class":127},[105,1966,237],{"class":236},[105,1968,159],{"class":127},[105,1970,246],{"class":111},[105,1972,341],{"class":127},[105,1974,1789],{"class":119},[105,1976,352],{"class":127},[105,1978,159],{"class":123},[105,1980,162],{"class":127},[105,1982,1983],{"class":107,"line":274},[105,1984,1985],{"class":569},"\u002F\u002F 符号模式 Node.js 不直接支持，需用数字或相应对照\n",[105,1987,1988,1990,1992,1994,1996,1998,2000,2002,2004,2006,2009,2011],{"class":107,"line":293},[105,1989,1145],{"class":254},[105,1991,124],{"class":123},[105,1993,128],{"class":127},[105,1995,1923],{"class":131},[105,1997,135],{"class":123},[105,1999,1769],{"class":138},[105,2001,143],{"class":142},[105,2003,1769],{"class":138},[105,2005,148],{"class":127},[105,2007,2008],{"class":557}," 0o755",[105,2010,159],{"class":123},[105,2012,162],{"class":127},[28,2014,2015,2016,2019,2020,2023],{},"其他相关 API：",[32,2017,2018],{},"fs.stat"," 获取当前权限，",[32,2021,2022],{},"fs.access"," 检查权限。",[69,2025,2027],{"id":2026},"_5-软链接符号链接与硬链接","5. 软链接（符号链接）与硬链接",[74,2029,2030],{},[77,2031,2032,2035],{},[36,2033,2034],{},"软链接","：类似于快捷方式，可以跨文件系统。",[96,2037,2039],{"className":98,"code":2038,"language":100,"meta":101,"style":101},"fs.symlink('.\u002Ftarget.txt', '.\u002Flink.txt', (err) => { ... });\n\u002F\u002F 读取链接指向的路径\nconst realPath = await fs.readlink('.\u002Flink.txt');\n",[32,2040,2041,2088,2093],{"__ignoreMap":101},[105,2042,2043,2045,2047,2050,2052,2054,2057,2059,2061,2063,2066,2068,2070,2072,2074,2076,2078,2080,2082,2084,2086],{"class":107,"line":108},[105,2044,13],{"class":123},[105,2046,128],{"class":127},[105,2048,2049],{"class":131},"symlink",[105,2051,135],{"class":123},[105,2053,1769],{"class":138},[105,2055,2056],{"class":142},".\u002Ftarget.txt",[105,2058,1769],{"class":138},[105,2060,148],{"class":127},[105,2062,1854],{"class":138},[105,2064,2065],{"class":142},".\u002Flink.txt",[105,2067,1769],{"class":138},[105,2069,148],{"class":127},[105,2071,233],{"class":127},[105,2073,237],{"class":236},[105,2075,159],{"class":127},[105,2077,246],{"class":111},[105,2079,341],{"class":127},[105,2081,1789],{"class":119},[105,2083,352],{"class":127},[105,2085,159],{"class":123},[105,2087,162],{"class":127},[105,2089,2090],{"class":107,"line":165},[105,2091,2092],{"class":569},"\u002F\u002F 读取链接指向的路径\n",[105,2094,2095,2097,2100,2102,2104,2106,2108,2111,2113,2115,2117,2119,2121],{"class":107,"line":274},[105,2096,112],{"class":111},[105,2098,2099],{"class":115}," realPath",[105,2101,120],{"class":119},[105,2103,391],{"class":254},[105,2105,124],{"class":123},[105,2107,128],{"class":127},[105,2109,2110],{"class":131},"readlink",[105,2112,135],{"class":123},[105,2114,1769],{"class":138},[105,2116,2065],{"class":142},[105,2118,1769],{"class":138},[105,2120,159],{"class":123},[105,2122,162],{"class":127},[74,2124,2125],{},[77,2126,2127,2130],{},[36,2128,2129],{},"硬链接","：多个文件名指向同一个 inode，不能跨文件系统。",[96,2132,2134],{"className":98,"code":2133,"language":100,"meta":101,"style":101},"fs.link('.\u002Foriginal.txt', '.\u002Fhardlink.txt', (err) => { ... });\n",[32,2135,2136],{"__ignoreMap":101},[105,2137,2138,2140,2142,2145,2147,2149,2152,2154,2156,2158,2161,2163,2165,2167,2169,2171,2173,2175,2177,2179,2181],{"class":107,"line":108},[105,2139,13],{"class":123},[105,2141,128],{"class":127},[105,2143,2144],{"class":131},"link",[105,2146,135],{"class":123},[105,2148,1769],{"class":138},[105,2150,2151],{"class":142},".\u002Foriginal.txt",[105,2153,1769],{"class":138},[105,2155,148],{"class":127},[105,2157,1854],{"class":138},[105,2159,2160],{"class":142},".\u002Fhardlink.txt",[105,2162,1769],{"class":138},[105,2164,148],{"class":127},[105,2166,233],{"class":127},[105,2168,237],{"class":236},[105,2170,159],{"class":127},[105,2172,246],{"class":111},[105,2174,341],{"class":127},[105,2176,1789],{"class":119},[105,2178,352],{"class":127},[105,2180,159],{"class":123},[105,2182,162],{"class":127},[74,2184,2185],{},[77,2186,2187,2190,2191,2194,2195,2198,2199,67],{},[36,2188,2189],{},"判断是否为软链接","：通过 ",[32,2192,2193],{},"fs.lstat"," 获取文件信息，",[32,2196,2197],{},"stats.isSymbolicLink()"," 返回 ",[32,2200,2201],{},"true",[69,2203,2205],{"id":2204},"_6-目录操作","6. 目录操作",[74,2207,2208,2220,2228,2237],{},[77,2209,2210,94,2213,2216,2217,2219],{},[36,2211,2212],{},"创建目录",[32,2214,2215],{},"fs.mkdir(path, { recursive: true }, callback)","（",[32,2218,1407],{}," 可创建多级目录）",[77,2221,2222,94,2225],{},[36,2223,2224],{},"读取目录内容",[32,2226,2227],{},"fs.readdir(path, (err, files) => {...})",[77,2229,2230,94,2233,2236],{},[36,2231,2232],{},"删除空目录",[32,2234,2235],{},"fs.rmdir(path)","（需为空）",[77,2238,2239,2242,2243,2246],{},[36,2240,2241],{},"删除非空目录","：可使用 ",[32,2244,2245],{},"fs.rm(path, { recursive: true, force: true })","（Node.js 14+）",[49,2248,2249],{"id":2249},"总结表",[2251,2252,2253,2270],"table",{},[2254,2255,2256],"thead",{},[2257,2258,2259,2263,2266,2268],"tr",{},[2260,2261,2262],"th",{},"操作类型",[2260,2264,2265],{},"异步回调",[2260,2267,46],{},[2260,2269,38],{},[2271,2272,2273,2294,2313,2333,2353,2373,2393,2413,2433],"tbody",{},[2257,2274,2275,2279,2284,2289],{},[2276,2277,2278],"td",{},"读取文件",[2276,2280,2281],{},[32,2282,2283],{},"fs.readFile",[2276,2285,2286],{},[32,2287,2288],{},"fs.promises.readFile",[2276,2290,2291],{},[32,2292,2293],{},"fs.readFileSync",[2257,2295,2296,2298,2303,2308],{},[2276,2297,1620],{},[2276,2299,2300],{},[32,2301,2302],{},"fs.writeFile",[2276,2304,2305],{},[32,2306,2307],{},"fs.promises.writeFile",[2276,2309,2310],{},[32,2311,2312],{},"fs.writeFileSync",[2257,2314,2315,2318,2323,2328],{},[2276,2316,2317],{},"追加内容",[2276,2319,2320],{},[32,2321,2322],{},"fs.appendFile",[2276,2324,2325],{},[32,2326,2327],{},"fs.promises.appendFile",[2276,2329,2330],{},[32,2331,2332],{},"fs.appendFileSync",[2257,2334,2335,2338,2343,2348],{},[2276,2336,2337],{},"删除文件",[2276,2339,2340],{},[32,2341,2342],{},"fs.unlink",[2276,2344,2345],{},[32,2346,2347],{},"fs.promises.unlink",[2276,2349,2350],{},[32,2351,2352],{},"fs.unlinkSync",[2257,2354,2355,2358,2363,2368],{},[2276,2356,2357],{},"重命名",[2276,2359,2360],{},[32,2361,2362],{},"fs.rename",[2276,2364,2365],{},[32,2366,2367],{},"fs.promises.rename",[2276,2369,2370],{},[32,2371,2372],{},"fs.renameSync",[2257,2374,2375,2378,2383,2388],{},[2276,2376,2377],{},"修改权限",[2276,2379,2380],{},[32,2381,2382],{},"fs.chmod",[2276,2384,2385],{},[32,2386,2387],{},"fs.promises.chmod",[2276,2389,2390],{},[32,2391,2392],{},"fs.chmodSync",[2257,2394,2395,2398,2403,2408],{},[2276,2396,2397],{},"创建软链接",[2276,2399,2400],{},[32,2401,2402],{},"fs.symlink",[2276,2404,2405],{},[32,2406,2407],{},"fs.promises.symlink",[2276,2409,2410],{},[32,2411,2412],{},"fs.symlinkSync",[2257,2414,2415,2418,2423,2428],{},[2276,2416,2417],{},"创建硬链接",[2276,2419,2420],{},[32,2421,2422],{},"fs.link",[2276,2424,2425],{},[32,2426,2427],{},"fs.promises.link",[2276,2429,2430],{},[32,2431,2432],{},"fs.linkSync",[2257,2434,2435,2438,2442,2445],{},[2276,2436,2437],{},"监视变化",[2276,2439,2440],{},[32,2441,1177],{},[2276,2443,2444],{},"无",[2276,2446,2444],{},[28,2448,2449,94],{},[36,2450,2451],{},"最佳实践",[74,2453,2454,2462,2470,2480],{},[77,2455,2456,2457,481,2459,2461],{},"对于大文件处理，始终使用流（",[32,2458,480],{},[32,2460,484],{},"）。",[77,2463,2464,2465,2467,2468,67],{},"对于简单操作，优先选择 ",[32,2466,307],{}," API 配合 ",[32,2469,318],{},[77,2471,2472,2473,1055,2476,2479],{},"注意使用 ",[32,2474,2475],{},"try\u002Fcatch",[32,2477,2478],{},"catch"," 处理 Promise 拒绝。",[77,2481,2482],{},"文件监视时，考虑防抖\u002F节流以减少频繁回调。",[23,2484,2485],{"id":2485},"推荐参考资料",[74,2487,2488,2498,2506],{},[77,2489,2490,2491],{},"Node.js 官方文档 ",[2492,2493,2497],"a",{"href":2494,"rel":2495},"https:\u002F\u002Fnodejs.org\u002Fapi\u002Ffs.html",[2496],"nofollow","File system",[77,2499,2500,2501],{},"深入理解流式 API： ",[2492,2502,2505],{"href":2503,"rel":2504},"https:\u002F\u002Fnodejs.org\u002Fapi\u002Fstream.html",[2496],"Stream API 指南",[77,2507,2508,2509,2512],{},"实用工具：",[32,2510,2511],{},"fs-extra"," 库（提供了更友好的 Promise API 和额外方法）",[2514,2515,2516],"style",{},"html pre.shiki code .sbsja, html code.shiki .sbsja{--shiki-light:#9C3EDA;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .s_hVV, html code.shiki .s_hVV{--shiki-light:#90A4AE;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .smGrS, html code.shiki .smGrS{--shiki-light:#39ADB5;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .su5hD, html code.shiki .su5hD{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sP7_E, html code.shiki .sP7_E{--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sGLFI, html code.shiki .sGLFI{--shiki-light:#6182B8;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sjJ54, html code.shiki .sjJ54{--shiki-light:#39ADB5;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .s_sjI, html code.shiki .s_sjI{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s99_P, html code.shiki .s99_P{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#FFAB70;--shiki-dark-font-style:inherit}html pre.shiki code .sVHd0, html code.shiki .sVHd0{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit}html pre.shiki code .skxfh, html code.shiki .skxfh{--shiki-light:#E53935;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .srdBf, html code.shiki .srdBf{--shiki-light:#F76D47;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sutJx, html code.shiki .sutJx{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}html pre.shiki code .syTEX, html code.shiki .syTEX{--shiki-light:#FF5370;--shiki-default:#005CC5;--shiki-dark:#79B8FF}",{"title":101,"searchDepth":165,"depth":165,"links":2518},[2519,2527],{"id":25,"depth":165,"text":26,"children":2520},[2521,2522,2524,2525,2526],{"id":51,"depth":274,"text":52},{"id":476,"depth":274,"text":2523},"二、流式读写（createReadStream \u002F createWriteStream）",{"id":1170,"depth":274,"text":1171},{"id":1592,"depth":274,"text":1593},{"id":2249,"depth":274,"text":2249},{"id":2485,"depth":165,"text":2485},{"title":8,"description":9},"knowledge\u002Fbooklet\u002Fend\u002FNodeJs\u002Fcore\u002Ffs","knowledge\u002Fknowledge\u002Fbooklet\u002Fend\u002FNodeJs\u002Fcore\u002Ffs.md","md",{"items":2533},[2534,2538,2542,2546,2550,2554],{"path":2535,"title":2536,"description":2537,"category":10,"score":608},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnodejs\u002Fcore\u002Fbuffer","缓冲区","Buffer 是 Node.js 全局对象，用于处理二进制数据流（如文件、网络数据）。在 ES6 引入 TypedArray 之前，Buffer 是 Node.js 处理二进制的主要方式；现在 Buffer 实现了 Uint8Arra…",{"path":2539,"title":2540,"description":2541,"category":10,"score":608},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnodejs\u002Fcore\u002Fpath","路径处理","path 模块提供了用于处理和转换文件路径的实用工具。它是 Node.js 核心模块，无需安装即可直接使用。由于不同操作系统（Windows、Linux、macOS）的路径分隔符不同（Windows 使用反斜杠 \\，POSIX 使用正…",{"path":2543,"title":2544,"description":2545,"category":10,"score":608},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnodejs\u002Fcore\u002Fprocess","进程与子进程","Node.js 在单个进程中运行，但通过 process 对象、child_process 模块及 worker_threads 模块提供了对进程的精细控制以及多进程\u002F多线程能力。下面从三个方面展开。",{"path":2547,"title":2548,"description":2549,"category":10,"score":608},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnodejs\u002Fcore\u002Fhttp","网络编程","Node.js 提供了丰富的内置模块，用于构建网络应用。下面从 HTTP\u002FHTTPS、WebSocket、TCP\u002FUDP 以及 DNS 解析四个方面进行深入介绍。",{"path":2551,"title":2552,"description":2553,"category":10,"score":608},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnodejs\u002Fcore\u002Fstream","流","流是 Node.js 中处理有序数据的抽象接口，用于以连续方式异步读取或写入数据。它们特别适合处理大文件、网络通信或任何可能无限产生的数据。Node.js 内置的 stream 模块提供了四种基本流类型，以及用于组合和错误处理的工具函数。",{"path":2555,"title":2556,"description":2557,"category":10,"score":608},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnodejs\u002Fcore\u002Fother","其他常用模块","以下是 Node.js 中几个重要内置模块的详细介绍，涵盖事件触发器、定时器、加密、压缩、操作系统信息和实用工具。",{"series":2559,"title":2560,"items":2561,"index":108,"prev":2575,"next":2576},"booklet\u002Fend\u002Fnodejs\u002Fcore","core",[2562,2564,2565,2567,2569,2571,2573],{"path":2535,"title":2536,"date":2563,"pinned":15},"2025-01-30",{"path":7,"title":8,"date":14,"pinned":15},{"path":2547,"title":2548,"date":2566,"pinned":15},"2023-01-27",{"path":2555,"title":2556,"date":2568,"pinned":15},"2020-03-27",{"path":2539,"title":2540,"date":2570,"pinned":15},"2024-03-14",{"path":2543,"title":2544,"date":2572,"pinned":15},"2023-11-10",{"path":2551,"title":2552,"date":2574,"pinned":15},"2022-05-03",{"path":2535,"title":2536,"date":2563,"pinned":15},{"path":2547,"title":2548,"date":2566,"pinned":15}]