3.path 路径模块

 

1.解决路径拼接的问题

在使用 fs 模块操作文件时,如果提供的操作路径是以 ./ 或 ../ 开头的相对路径时,很容易出现路径动态拼接错误的问题。

原因:代码在运行的时候,会以执行 node 命令时所处的目录,动态拼接出被操作文件的完整路径。

解决方案:在使用 fs 模块操作文件时,直接提供完整的路径,不要提供 ./ 或 ../ 开头的相对路径,从而防止路径动态拼接的问题。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
const fs = require('fs');

// 出现路径拼接错误的问题,是因为提供了 ./ 或 ../ 开头的相对路径
// 如果要解决这个问题,可以直接提供一个完整的文件存放路径就行
/**
* fs.readFile()读取文件的路径 = [执行 node 命令时所在的目录] + [/files/1.txt]
* 所以读取文件的路径与执行 node 命令时所在的目录有关,路径所指向的文件可能不存在,
* 如果在文件所在的目录下执行node [文件]命令,则可以读取到该文件
* 如果不是在文件所在的目录下执行node [文件]命令,例如在文件所在的目录的上级目录,则会找不到该文件
*/
fs.readFile('./files/1.txt', 'utf8', function(err, dataStr) {
if (err) {
return console.log('读取文件失败!' + err.message);
}
console.log('读取文件成功!' + dataStr);
});

// 解决方案一:直接写文件的绝对路径
// 移植性非常差、不利于维护
fs.readFile('C:/Users/escook/Desktop/Node.js基础/day1/code/files/1.txt', 'utf8', function(err, dataStr) {
if (err) {
return console.log('读取文件失败!' + err.message);
}
console.log('读取文件成功!' + dataStr);
});

// __dirname 表示当前文件所处的目录
console.log(__dirname);

fs.readFile(__dirname + '/files/1.txt', 'utf8', function(err, dataStr) {
if (err) {
return console.log('读取文件失败!' + err.message);
}
console.log('读取文件成功!' + dataStr);
});

2.path 路径模块

1.path.join([…paths]): 用来将多个路径片段拼接成一个完整的路径字符串

参数:

  • …paths(string):路径片段的序列
  • 返回值: string
1
2
3
4
5
6
7
8
9
10
11
12
13
14
const path = require('path')
const fs = require('fs')

// 注意: ../ 会抵消前面的路径
const pathStr = path.join('/a', '/b/c', '../../', './d', 'e');
console.log(pathStr);
// \a\d\e

fs.readFile(path.join(__dirname, './files/1.txt'), 'utf8', function(err, dataStr) {
if (err) {
return console.log(err.message);
}
console.log(dataStr);
})

2.path.basename(path[, ext]): 获取路径中的最后一部分,经常通过这个方法获取路径中的文件名

参数:

  • path: string, 必选参数,表示一个路径的字符串
  • ext: string, 可选参数,表示文件扩展名
  • 返回: string, 表示路径中的最后一部分
1
2
3
4
5
6
7
8
9
10
11
12
const path = require('path')

// 定义文件的存放路径
const fpath = '/a/b/c/index.html'

const fullName = path.basename(fpath)
console.log(fullName)
// index.html

const nameWithoutExt = path.basename(fpath, '.html')
console.log(nameWithoutExt)
// index

3.path.extname(path): 可以获取路径中的扩展名部分

参数:

  • path: string, 必选参数,表示一个路径的字符串
  • 返回: string, 返回得到的扩展名字符串
1
2
3
4
5
6
7
8
const path = require('path')

// 这是文件的存放路径
const fpath = '/a/b/c/index.html'

const fext = path.extname(fpath)
console.log(fext)
// .html

3.fs模块和path模块案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
// 1.1 导入 fs 模块
const fs = require('fs')
// 1.2 导入 path 模块
const path = require('path')

// 1.3 定义正则表达式,分别匹配 <style></style> 和 <script></script> 标签
const regStyle = /<style>[\s\S]*<\/style>/
const regScript = /<script>[\s\S]*<\/script>/

// 2.1 调用 fs.readFile() 方法读取文件
fs.readFile(path.join(__dirname, '../素材/index.html'), 'utf8', function(err, dataStr) {
// 2.2 读取 HTML 文件失败
if (err) return console.log('读取HTML文件失败!' + err.message)
// 2.3 读取文件成功后,调用对应的三个方法,分别拆解出 css, js, html 文件
resolveCSS(dataStr)
resolveJS(dataStr)
resolveHTML(dataStr)
})

// 3.1 定义处理 css 样式的方法
function resolveCSS(htmlStr) {
// 3.2 使用正则提取需要的内容
const r1 = regStyle.exec(htmlStr)
// 3.3 将提取出来的样式字符串,进行字符串的 replace 替换操作
const newCSS = r1[0].replace('<style>', '').replace('</style>', '')
// 3.4 调用 fs.writeFile() 方法,将提取的样式,写入到 clock 目录中 index.css 的文件里面
fs.writeFile(path.join(__dirname, './clock/index.css'), newCSS, function(err) {
if (err) return console.log('写入 CSS 样式失败!' + err.message)
console.log('写入样式文件成功!')
})
}

// 4.1 定义处理 js 脚本的方法
function resolveJS(htmlStr) {
// 4.2 通过正则,提取对应的 <script></script> 标签内容
const r2 = regScript.exec(htmlStr)
// 4.3 将提取出来的内容,做进一步的处理
const newJS = r2[0].replace('<script>', '').replace('</script>', '')
// 4.4 将处理的结果,写入到 clock 目录中的 index.js 文件里面
fs.writeFile(path.join(__dirname, './clock/index.js'), newJS, function(err) {
if (err) return console.log('写入 JavaScript 脚本失败!' + err.message)
console.log('写入 JS 脚本成功!')
})
}

// 5.1 定义处理 HTML 结构的方法
function resolveHTML(htmlStr) {
// 5.2 将字符串调用 replace 方法,把内嵌的 style 和 script 标签,替换为外联的 link 和 script 标签
const newHTML = htmlStr.replace(regStyle, '<link rel="stylesheet" href="./index.css" />').replace(regScript, '<script src="./index.js"></script>')
// 5.3 写入 index.html 这个文件
fs.writeFile(path.join(__dirname, './clock/index.html'), newHTML, function(err) {
if (err) return console.log('写入 HTML 文件失败!' + err.message)
console.log('写入 HTML 页面成功!')
})
}

注意:

  • fs.writeFile() 方法只能用来创建文件,不能用来创建路径
  • 重复调用 fs.writeFile() 写入同一个文件,新写入的内容会覆盖之前的旧内容