4、练习- 考试成绩整理
使用 fs 文件系统模块,将素材目录下成绩.txt文件中的考试数据,整理到 成绩-ok.txt 文件中
整理前,成绩.txt文件中的数据格式如下:
小红=99 小白=100 小黄=70 小黑=66 小绿=88
整理完成之后,希望得到的成绩-ok.txt文件中的数据格式如下:
小红:99 小白:100 小黄:70 小黑:66 小绿:88
核心实现步骤:
1、导入需要的 fs 文件系统模块
2、使用 fs.readFile() 方法,读取素材目录下的 成绩.txt 文件
3、判断文件是否读取失败
4、文件读取成功后,处理成绩数据
5、将处理完成的成绩数据,调用 fs.writeFile() 方法,写入到新文件 成绩-ok.txt 中
代码:
const fs = require("fs"); fs.readFile("../素材/成绩.txt", "utf8", (err, res) => { if (err) return console.log("文件复去失败!" + err.message); // 1、先把成绩的数据,按照空格进行分割 const arrOld = res.split(" "); // 2、循环分割后的数组,对每一项数据进行字符串的替换操作 const arrNew = []; arrOld.forEach((item) => { arrNew.push(item.replace("=", ":")); }); // 3、把新数组中的每一项,进行合并,得到一个新的字符串 const newStr = arrNew.join("\r\n"); // 数据写入成绩-ok.txt文件中 fs.writeFile("./files/成绩-ok.txt", newStr, (err) => { if (err) return console.log("写入成绩失败!" + err.message); console.log("写入成绩成功!"); }); });
5、fs模块 - 路径动态拼接的问题
说明:在使用 fs 模块操作文件时,如果提供的操作路径是以 ./ 或 …/ 开头的相对路径时,很容易出现路径动态拼接错误的问题。
原因:代码在运行的时候,会以执行 node 命令时所处的目录,动态拼接出被操作文件的完整路径。
解决方案:在使用 fs 模块操作文件时,直接提供完整的路径,不要提供 ./ 或 …/ 开头的相对路径,从而防止路径动态拼接的问题。
// windows下绝对路径演示 D:\code\files\1.txt
// 相对路径 fs.readFile("./files/1.txt", "utf8", (err, res) => { if (err) return console.log("读取文件失败!" + err); console.log("读取文件成功!" + res); }); // 拼接绝对路径 // __dirname表示当前文件所处的目录 fs.readFile(__dirname + "/files/1.txt", "utf8", (err, res) => { if (err) return console.log("读取文件失败!" + err); console.log("读取文件成功!" + res); });
path路径模块
1、什么是 path 路径模块
说明:path 模块是 Node.js 官方提供的、用来处理路径的模块。它提供了一系列的方法和属性,用来满足用户对路径的处理 需求。
例如: path.join() 方法,用来将多个路径片段拼接成一个完整的路径字符串
path.basename() 方法,用来从路径字符串中,将文件名解析出来
如果要在 JavaScript 代码中,使用 path 模块来处理路径,则需要使用如下的方式先导入它:
const path = reqiure('path');
2、路径拼接
- path.join() 的语法格式
使用 path.join() 方法,可以把多个路径片段拼接为完整的路径字符串,语法格式如下:
path.join([...paths]);
参数解读:
参数 | 说明 |
…paths | 路径片段的序列 |
返回值 | 拼接完成的返回值 |
path.join() 的代码示例
使用 path.join() 方法,可以把多个路径片段拼接为完整的路径字符串:
const path = require("path"); const pathStr = path.join("/a", "/b/c", "../", "./d", "e");
- 注意:今后凡是涉及到路径拼接的操作,都要使用 path.join() 方法进行处理。不要直接使用 + 进行字符串的拼接。
3、 获取路径中的文件名
path.basename() 的语法格式
说明:使用 path.basename() 方法,可以获取路径中的最后一部分,经常通过这个方法获取路径中的文件名。
path.basename(path[, ext]);
参数说明:
参数 | 说明 |
path | 必选参数,表示一个路径的字符串 |
ext | 可选参数,表示文件扩展名 |
返回值 | 获取后的返回值 |
path.basename() 代码示例
const fpath = "/a/b/c/index.html"; // 获取完整文件名 const fullName = path.basename(fpath); console.log(fullName); // index.html // basename方法第二个参数为文件扩展名,加上扩展名后得到的是纯文件名 const nameWithoutExt = path.basename(fullName, ".html"); console.log(nameWithoutExt); // index
4、获取路径中的文件扩展名
- path.extname() 的语法格式
path.extname(path)
- 参数解读:
path
必选参数,表示一个路径的字符串- 返回: 返回得到的扩展名字符串
- path.extname() 代码示例
// path 为文件存放路径 const fpath = '/a/b/c/index.html' const name = path.extname(fpath) console.log(name) // .html
综合案例
要求:将素材目录下的 index.html 页面, 拆分成三个文件,分别是:index.css、index.js、index.html,并且将拆分出来的 3 个文件,存 放到 clock 目录中。
- 实现步骤
1、创建两个正则表达式,分别用来匹配<style>
和<script>
标签
2、使用 fs 模块,读取需要被处理的 HTML 文件
3、自定义 resolveCSS 方法,来写入 index.css 样式文件
4、自定义 resolveJS 方法,来写入 index.js 脚本文件
5、自定义 resolveHTML 方法,来写入 index.html 文件
- 步骤一:导入需要的模块并创建正则表达式
// 1.1导入 fs 模块 const fs = require("fs"); // 1.2导入 path 模块 const path = require("path"); // 1.3定义正则表达式,分别匹配 <style></style> 和 <script></script> 标签 // /s 代表匹配空白字符,/S 表示匹配任意非空白字符字符 /s/S 表示匹配任意字符 * 表示可以出现多次 const regStyle = /<style>[\s\S]*<\/style>/; const regScript = /<script>[/s/S]*<\/script>/;
步骤二: 使用 fs 模块读取需要被处理的html文件
// 2.1读取需要被处理的html文件 fs.readFile(path.join(__dirname, "../素材/index.html"), "utf8", (err, res) => { // 2.2读取html文件失败 if (err) return console.log("读取文件失败!" + err.message); // 2.3读取成功后需要调用对应的三个方法,分别拆解出css、js、html文件 resolveCSS(res); resolveJS(res); resolveHTML(res); });
步骤三:自定义resolveCSS方法
// 3.1处理css函数 function resolveCSS(htmlStr) { // 3.2使用正则提取页面中的 <style></style> 标签 const r1 = regStyle.exec(htmlStr); // 3.3将提取出来的样式字符,做进一步处理、 const newCSS = r1[0].replace("<style>", "").replace("</style>", ""); // 3.4将提取出来的css样式,写入到index.css文件中 fs.writeFile(path.join(__dirname, "./clock/index.css"), newCSS, (err) => { if (err) return console.log("css写入失败!" + err.message); console.log("文件写入成功!"); }); }
步骤四:自定义 resolveJS 方法
// 4.1处理js脚本函数 function resolveJS(htmlStr) { // 4.2使用正则提取页面中的 <script></script> 标签 const r2 = regScript.exec(htmlStr); // 4.3将提取出来的js脚本,做进一步处理 const newJS = r2[0].replace("<script>", "").replace("</script>", ""); // 4.4将处理好的js脚本写入到index.js文件中 fs.writeFile( path.join(__dirname, "./clock/index.js"), newJS, "utf8", (err) => { if (err) return console.log("js写入失败!" + err.message); console.log("js写入文件成功"); } ); }
步骤五:自定义 resolveHTML 方法
// 5.1处理html function resolveHTML(htmlStr) { // 5.1使用字符串的replace方法,把内嵌的<script></script>和<style></style>标签,替换为外链的<link>和<script>标签 const newHTML = htmlStr .replace(regStyle, '<link rel="stylesheet" href="./index.css">') .replace(regScript, "<script src='./index.js'></script>"); // 5.2将替换过后的html写入index.html文件中 fs.writeFile( path.join(__dirname, "./clock/index.html"), newHTML, (err) => { if (err) return console.log("html写入失败!" + err.message); console.log("html写入成功!"); } ); }
- 注意点:
1、fs.writeFile()
方法只能用来创建文件,不能用来创建路径
2、重复调用fs.writeFile()
写入同一个文件,新写入的内容会覆盖之前的旧内容