本文节选自《Nodejs学习笔记》,更多章节和更新请访问github主页地址。欢迎加入群交流,群号197339705。模块概述在nodejs中,path是一个使用频率很高,但又让人又爱又恨的模块。一部分是因为文档不够清晰,一部分是因为接口的平台差异。把path的接口按照用途分类,仔细考虑一下,就不会那么混乱了。获取路径/文件名/扩展名获取路径:path.dirname(filepath)获取文件名:path.basename(filepath)获取扩展名:path.extname(filepath)获取路径示例如下:varpath=require('path');varfilepath='/tmp/demo/js/test.js';//输出:/tmp/demo/jsconsole.log(path.dirname(filepath));严格来说,路径。basename(filepath)只是输出路径的最后一部分,不会判断是否为文件名。但大多数时候,我们可以将其用作简单的“获取文件名”方法。varpath=require('path');//输出:test.jsconsole.log(path.basename('/tmp/demo/js/test.js'));//输出:testconsole.log(path.basename('/tmp/demo/js/test/'));//输出:testconsole.log(path.basename('/tmp/demo/js/test'));如果只想获取文件名,不包括文件扩展名呢?您可以使用第二个参数。//输出:testconsole.log(path.basename('/tmp/demo/js/test.js','.js'));获取文件扩展名的简单示例如下:varpath=require('path');varfilepath='/tmp/demo/js/test.js';//output:.jsconsole.log(path.extname(文件路径));更详细的规则如下:(假设path.basename(filepath)===B)从最后一个截取。B直到最后一个字符。如果。B中不存在,或者B的第一个字符是.,则返回空字符串。直接看官方文档例子path.extname('index.html')//returns'.html'path.extname('index.coffee.md')//returns'.md'path.extname('index.html')')//返回'.'path.extname('index')//返回''path.extname('.index')//返回''路径组合path.join([...paths])path.resolve([...paths])path.join([...paths])将路径放在一起,然后对其进行规范化。这句话反正我是莫名其妙,大家可以参考下面的伪代码定义。示例:varpath=require('path');//输出'/foo/bar/baz/asdf'path.join('/foo','bar','baz/asdf','quux','..');路径定义的伪代码如下:module.exports.join=function(){varpaths=Array.prototye.slice.call(arguments,0);returnthis.normalize(paths.join('/'));};path.resolve([...paths])这个接口的描述有点啰嗦。你可以想象一下,你在shell下从左到右运行cdpath命令,最后得到的绝对路径/文件名就是这个接口返回的结果。例如path.resolve('/foo/bar','./baz')可以看做是下面命令的结果cd/foo/barcd./baz更多对比例子如下:varpath=require('path');//假设当前工作路径为/Users/a/Documents/git-code/nodejs-learning-guide/examples/2016.11.08-node-path//输出/Users/a/Documents/git-code/nodejs-learning-guide/examples/2016.11.08-node-pathconsole.log(path.resolve(''))//输出/Users/a/Documents/git-code/nodejs-learning-guide/examples/2016.11.08-node-pathconsole.log(path.resolve('.'))//输出/foo/bar/bazconsole.log(path.resolve('/foo/bar','./baz'));//输出/foo/bar/bazconsole.log(path.resolve('/foo/bar','./baz/'));//输出/tmp/fileconsole.log(path.resolve('/foo/bar','/tmp/file/'));//输出/Users/a/Documents/git-code/nodejs-learning-guide/examples/2016.11.08-node-path/www/js/mod.jsconsole.log(path.resolve('www','js/upload','../mod.js'));路径分析path.parse(path)path.normalize(filepath)从官方文档的描述来看,path.normalize(filepath)应该是一个比较简单的API,但是总感觉没什么用。为什么?API描述过于简单,主要包括以下内容:如果路径为空,则返回.,相当于当前工作路径。将路径中重复的路径分隔符(如linux下的/)合并为一个。处理路径中的.,..。(类似于shell中的cd..。)如果路径末尾有/,则保留/。感觉stackoverflow上有个师兄解释这个API比较实在,链接原文。换句话说,path.normalize是“我可以走的最短路径是什么,它将把我带到与输入相同的地方”代码示例如下。建议读者复制代码运行看看实际效果。varpath=require('path');varfilepath='/tmp/demo/js/test.js';varindex=0;varcompare=function(desc,callback){console.log('[用例%d]:%s',++index,desc);打回来();console.log('\n');};compare('路径为空',function(){//output.console.log(path.normalize(''));});compare('路径是否以/'结尾,function(){//输出/tmp/demo/js/uploadconsole.log(path.normalize('/tmp/demo/js/upload'));///tmp/demo/js/upload/console.log(path.normalize('/tmp/demo/js/upload/'));});compare('repeated/',function(){//输出/tmp/demo/jsconsole.log(path.normalize('/tmp/demo//js'));});compare('pathwith..',function(){//输出/tmp/demo/jsconsole.log(path.normalize('/tmp/demo/js/upload/..'));});compare('相对路径',function(){//输出demo/js/upload/console.log(path.normalize('./demo/js/upload/'));//输出demo/js/upload/console.log(path.normalize('demo/js/upload/'));});compare('Uncommonboundaries',function(){//输出..console.log(path.normalize('./..'));//输出..console.log(path.normalize('..'));//输出../console.log(path.normalize('../'));//输出/console.log(path.normalize('/../'));//输出/console.log(path.normalize('/..'));});有兴趣的可以看看path.normalize(filepath)的节点源码如下:pathObject按照一定的规则转化为文件路径path.parse(filepath):path.format()方法的逆向操作。我们来看看官网对相关属性的描述。首先是linux下┌────────────────────┬────────────┐│dir│base│├──────┬├──────┬──────┤│root││name│ext│"/home/user/dir/file.txt"└──────┴────────────────┴────────┴──────┘(应忽略“”行中的所有空格——它们纯粹用于格式化)然后是windows下┌————──────────────────┬────────────┐│dir│base│├────────┬├──────┬──────┤│root││name│ext│"C:\path\dir\file.txt"└──────┴────────────────┴──────┴──────┘(应忽略“”行中的所有空格——它们纯粹用于格式化)path.format(pathObject)阅读相关API文档说明后发现,path.format(pathObject)中,pathObject的配置属性是可以一步步精简的。根据接口的描述来看,下面两人是等价的。rootvsdir:两人可以相互替换,区别在,路征不会自动加/,而dir会。basevsname+ext:两人可以相互替换。varpath=require('path');varp1=path.format({root:'/tmp/',base:'hello.js'});控制台日志(p1);//输出/tmp/hello.jsvarp2=path.format({dir:'/tmp',name:'hello',ext:'.js'});控制台日志(p2);//输出/tmp/hello.jspath.parse(filepath的逆向操作)path.format(pathObject),直接去官网看例子。这四个属性对于用户来说非常方便,但是path.format(pathObject)中还有四个配置属性,有点让人摸不着头脑。path.parse('/home/user/dir/file.txt')//返回//{//root:"/",//dir:"/home/user/dir",//base:"file.txt",//ext:".txt",//name:"file"//}获取相对路径接口:path.relative(from,to)说明:从from路径到相对路径到to小路。边界:如果from和to指向相同的路径,则返回一个空字符串。如果from和to中有一个为空,则返回当前工作路径。上面的例子:varpath=require('path');varp1=path.relative('/data/orandea/test/aaa','/data/orandea/impl/bbb');控制台日志(p1);//输出"../../impl/bbb"varp2=path.relative('/data/demo','/data/demo');console.log(p2);//输出""varp3=path.relative('/data/demo','');console.log(p3);//output"../../Users/a/Documents/git-code/nodejs-learning-guide/examples/2016.11.08-node-path"平台相关接口/属性以下属性和接口是相关的平台的具体实施。换句话说,相同的属性和接口在不同的平台上表现不同。path.posix:路径相关属性和接口的Linux实现。path.win32:路径相关属性和接口的win32实现。path.sep:路径分隔符。在Linux上是/,在Windows上是``。path.delimiter:路径设置的分隔符。在linux上是:,在windows上是;。注意在使用path.win32相关接口时,参数也可以使用/作为分隔符,但是接口返回值的分隔符只会是``。直接来例子比较直观。>path.win32.join('/tmp','fuck')'\\tmp\\fuck'>path.win32.sep'\\'>path.win32.join('\tmp','demo')'\\tmp\\demo'>path.win32.join('/tmp','demo')'\\tmp\\demo'path.delimiterlinux系统示例:console.log(process.env.PATH)//'/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin'process.env.PATH.split(path.delimiter)//返回['/usr/bin','/bin','/usr/sbin','/sbin','/usr/local/bin']windows系统示例:console.log(process.env.PATH)//'C:\Windows\system32;C:\Windows;C:\ProgramFiles\node\'process.env.PATH.split(path.delimiter)//返回['C:\\Windows\\system32','C:\\Windows','C:\\ProgramFiles\\node\\']相关链接官方文档:https://nodejs.org/api/path.h...
