node 中的path.resolve和path.join的区别

208 阅读5分钟

一、path.resolve([...paths])

官网的解释

将路径或路径的片段的序列解析为绝对路径
拼接注意点:
1.给定的路径序列是从右向左处理,每个后续的path会追加到前面,直到构建成绝对路径
2.如果处理完所有给定的path片段,还没有生成绝对路径,则使用当前的工作目录
3.生成的路径被规范化,并且删除尾部斜杠(除非路径解析为根目录)
4.零长度的path片段被忽略
5.如果没有传入path片段,则path.resolve()则返回当前工作目录的绝对路径

如果官网的定义没有太明白,可以简单理解对这些路径逐一进行cd操作,与cd操作不同的是,这些路径可以是文件,并且可不必实际存在(resolve方法不会利用底层的文件系统判断文件是否存在,而只是进行路径字符串操作)
参考链接1
参考链接2

官网案例:

eg1: path.resolve('/foo/bar', './baz') 
理解:
最后一个路径相对路径,需要向前拼接
cd 理解法
cd /foo/bar ---/foo/bar
cd ./baz    ---/foo/bar/baz    遇到./直接拼接  -cd ./baz和cd baz都是进入baz目录

// 输出结果: '/foo/bar/baz'

eg2: path.resolve('/foo/bar', '/tmp/file/') 
理解:
/tmp/file/为绝对路径不拼接故直接输出,并且删除结尾的斜杠

// 输出结果:'/tmp/file' 

eg3: path.resolve('wwwroot', 'static_files/png/', '../gif/image.gif') 
// 当前的工作路径是 /home/itbilu/node,则输出结果为 
理解:(cd 理解法)
后俩个路径均不是绝对路径,所以需要跟前边的路径进行拼接处理,第一个路径也不是绝对路径,所以需要跟当前文件所在的目录的绝对路径进行拼接
cd理解法处理:
cd wwwroot----- /home/itbilu/node/wwwroot
cd static_files/png/----/home/itbilu/node/wwwroot/static_files/png/
cd ../gif/image.gif --/home/itbilu/node/wwwroot/static_files/gif/image.gif  遇到../退一个路径节点

输出结果:'/home/itbilu/node/wwwroot/static_files/gif/image.gif'

更多案例分析:

var path = require("path")     //引入node的path模块

path.resolve('/foo/bar', './baz')   // returns '/foo/bar/baz'
理解:从右向左看,直到遇到或拼接绝对路径,才会停止拼接,./baz不是绝对路径
cd 理解拼接
cd /foo/bar   -/foo/bar
cd ./baz      -/foo/bar/baz    遇到./直接拼接

path.resolve('/foo/bar', 'baz')   // returns '/foo/bar/baz'
理解:从右向左看,baz不为绝对路径
cd 理解拼接
cd /foo/bar   -/foo/bar
cd baz      -/foo/bar/baz    遇到不带符号,直接拼接,运行foo/bar+/+baz   

path.resolve('/foo/bar', '/baz')   // returns '/baz'
理解:从右向左看,/baz为绝对路径
最后一位为绝对路径,所以不拼接,直接输出

path.resolve('/foo/bar', '../baz')   // returns '/foo/baz'
理解:从右向左,../baz不为绝对路径,拼接
cd 理解法:
cd /foo/bar  /foo/bar
cd ../baz    /foo/baz    遇到../需要上退一个路径节点

path.resolve('/home','/foo/bar', '../baz')   // returns '/foo/baz'
理解:从右向左,../baz不为绝对路径,所以需要向前拼接,/foo/baz为绝对路径,不向前拼接
cd /foo/bar   /foo/bar
cd ../baz     /foo/baz   ../向前退一个节点

path.resolve('/home','./foo/bar', '../baz')   // returns '/home/foo/baz'
理解:从右向左,../baz,./foo/baz不为绝对路径,所以需要向前拼接,/home为绝对路径,不向前拼接(即和文件目录绝对路径拼接)
cd /home      /home
cd /foo/bar   /home/foo/bar
cd ../baz     /home/foo/baz   ../向前退一个节点

path.resolve('/home','foo/bar', '../baz')   // returns '/home/foo/baz'

知识点总结:
1.首先从右向左看路径片段,是否为绝对路径,如果为绝对路径,直接输出,如果不为绝对路径,一直向前追加,直到构成一个绝对路径为止
2.在拼接中用cd法拼接,从左向右看,按照cd的规则进行
3..字符以 / 开头,不会拼接到前面的路径(因为拼接到此已经是一个绝对路径)
4.以 …/ 开头,拼接前面的路径,且不含最后一节路径
5.以 ./ 开头 或者没有符号 则拼接前面路径;
6.如果没有传入参数,将返回当前根目录
参考链接

二、path.join([...paths])

官网解释:

使用特定于平台的分隔符(unix系统是 / ,windows系统是 \)作为定界符将所有给定的 path 片段连接在一起,然后规范化生成的路径。
1.零长度的 path 片段被忽略
2.如果连接的路径字符串是零长度字符串,则将返回 '.',表示当前工作目录。
3.如果任何路径片段不是字符串,则抛出 TypeError。

官网案例:

path.join('/foo', 'bar', 'baz/asdf', 'quux', '..');
// 返回: '/foo/bar/baz/asdf'

path.join('foo', {}, 'bar');
// 抛出 'TypeError: Path must be a string. Received {}'

三、二者的区别

1.join是把各个path片段连接在一起,resolve把' / ' 当成根目录

path.join('/a', '/b'); 
return /a/b
path.resolve('/a', '/b');
return  /b

2.resolve在传入非 / 路径时,会自动加上当前目录形成一个绝对路径,而join仅仅用于路径拼接

// 当前路径为
/Users/xiao/work/test
path.join('a', 'b', '..', 'd');
return  a/d
path.resolve('a', 'b', '..', 'd');
return  /Users/xiao/work/test/a/d

四、两个小点,关于__dirname,__filename

  1. __dirname 可以用来动态获取当前文件所属目录的绝对路径
  2. __filename 可以用来动态获取当前文件的绝对路径,包含当前文件
    // __dirname 和 __filename 是不受执行 node 命令所属路径影响的

练习:
1.建立一个js文件
2.使用node 文件名运行js文件,就能看到输出(前提安装node)

var path = require('path'); //引入node中的path模块

var dirName = path.resolve(__dirname)
console.log('__dirname:',dirName)  // D:\webLearn\Learn-littlebit\node\path
console.log('__filename:',path.resolve(__filename)) //D:\webLearn\Learn-littlebit\node\path\pathMethod.js