Node入門教程(8)第六章:path 模塊詳解

path 模塊詳解

path 模塊提供了一些工具函數(shù),用于處理文件與目錄的路徑。由于windows和其他系統(tǒng)之間路徑不統(tǒng)一捎琐,path模塊還專門做了相關(guān)處理,屏蔽了彼此之間的差異裹匙。

可移植操作系統(tǒng)接口(POSIX)

可移植操作系統(tǒng)接口(英語:Portable Operating System Interface瑞凑,縮寫為POSIX),是IEEE為要在各種UNIX操作系統(tǒng)上運行軟件幻件,而定義API的一系列互相關(guān)聯(lián)的標(biāo)準(zhǔn)的總稱拨黔,其正式稱呼為IEEE Std 1003蛔溃,而國際標(biāo)準(zhǔn)名稱為ISO/IEC 9945绰沥。此標(biāo)準(zhǔn)源于一個大約開始于1985年的項目。POSIX這個名稱是由理查德·斯托曼應(yīng)IEEE的要求而提議的一個易于記憶的名稱贺待。它基本上是Portable Operating System Interface(可移植操作系統(tǒng)接口)的縮寫徽曲,而X則表明其對Unix API的傳承。

Linux基本上逐步實現(xiàn)了POSIX兼容麸塞,但并沒有參加正式的POSIX認(rèn)證秃臣。

微軟的Windows NT聲稱部分實現(xiàn)了POSIX標(biāo)準(zhǔn)。

當(dāng)前的POSIX主要分為四個部分:Base Definitions哪工、System Interfaces奥此、Shell and Utilities和Rationale。

綜述:目前主流的類Unix操作系統(tǒng):Unix雁比、Linux都會兼容POSIX的標(biāo)準(zhǔn)稚虎,而Windows只是部分實行了POSIX標(biāo)準(zhǔn),所以后面我們說POSIX系統(tǒng)是指類Unix系統(tǒng)

windows系統(tǒng)和類Unix系統(tǒng)的路徑的區(qū)別

目錄結(jié)構(gòu)的區(qū)別

可能大家比較熟悉windows資源管理系統(tǒng)偎捎,windows是分不同的磁盤蠢终,然后磁盤下面都是樹狀結(jié)構(gòu)的文件和文件夾。

而類Unix(Unix茴她、Linux)系統(tǒng)中是不分盤符的寻拂,只有一個根目錄 /, 都是都是這個下面的子目錄或者文件丈牢,當(dāng)然也是樹狀的機構(gòu)祭钉。

Linux的目錄結(jié)構(gòu)

路徑的區(qū)別

除了目錄結(jié)構(gòu)有區(qū)別外,路徑也是有區(qū)別的己沛。windows是用反斜杠\分割目錄或者文件的慌核,而在類Unix的系統(tǒng)中是用的/帕识。

windows的路徑: C:\temp\myfile.html
類Unix的路徑:  /tmp/myfile.html

path模塊獲取路徑中的文件名

語法:path.basename(path[, ext])

參數(shù):

  • path <string> 完整文件名路徑
  • ext <string> 可選的文件擴展名
  • 返回: <string> 文件名

例如:

path.basename('/foo/bar/baz/asdf/quux.html');
// 返回: 'quux.html'

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

注意:如果 path 不是一個字符串或提供了 ext 但不是一個字符串,則拋出 TypeError遂铡。

完整實例:

const path = require('path');  // 引入path模塊
let linuxPath = '/Users/aicoder/abc.html';
let name = path.basename(linuxPath);
console.log(name);

let winPath = 'c:\\temp\\abc.html';
let winName = path.basename(winPath); // mac下面不能兼容輸出
console.log(winName);

console.log(path.basename(linuxPath, '.html'));  // => abc,去掉后綴輸出文件名

// mac的執(zhí)行輸出結(jié)果肮疗,其中有兼容問題
abc.html
c:\temp\abc.html
abc

node提供了win32和posix兼容的api

默認(rèn)情況下,node會根據(jù)不同的系統(tǒng)做相關(guān)兼容處理扒接,力保輸出的結(jié)果在不同平臺下是一致的伪货,但是某些情況下還是不能完美的兼容所有的情況。所以钾怔,node提供了win32posix各自對應(yīng)path的所有的api碱呼。也就是說:path模塊的api都可以通過path.win32 或者 path.posix調(diào)用。

要想在任何操作系統(tǒng)上處理 Windows 文件路徑時獲得一致的結(jié)果宗侦,可以使用 path.win32

path.win32.basename('C:\\temp\\myfile.html');
// 返回: 'myfile.html'

要想在任何操作系統(tǒng)上處理 POSIX 文件路徑時獲得一致的結(jié)果愚臀,可以使用 path.posix

path.posix.basename('/tmp/myfile.html');
// 返回: 'myfile.html'

其他api也是一致的,不再贅述矾利。

獲取路徑的文件夾

path.dirname() 方法返回一個 path 的目錄名姑裂。

語法: path.dirname(path)
參數(shù):

  • path <string> ,要返回路徑的變量
  • 返回: <string>
path.dirname('/foo/bar/baz/asdf/quux');
// 返回: '/foo/bar/baz/asdf'

獲取路徑的擴展名

path.extname() 方法返回 path 的擴展名男旗,即從 path 的最后一部分中的最后一個 .(句號)字符到字符串結(jié)束舶斧。
如果 path 的最后一部分沒有 . 或 path 的文件名的第一個字符是 .,則返回一個空字符串察皇。

語法: path.extname(path)

  • 參數(shù): path<string>類型茴厉。
  • 返回: <string>
path.extname('index.html');
// 返回: '.html'
path.extname('/etc/a/index.html');
// 返回: '.html'

path.extname('index.coffee.md');
// 返回: '.md'

path.extname('index.');
// 返回: '.'

path.extname('index');
// 返回: ''

path.extname('.index');
// 返回: ''

格式化一個路徑

path.format() 方法會從一個對象返回一個路徑字符串。

語法:path.format(pathObject)

  • pathObject <Object> 要轉(zhuǎn)換成路徑字符串的設(shè)置對象
    • dir <string> 所在目錄什荣,提供了 pathObject.dir矾缓,則 pathObject.root 會被忽略
    • root <string> 根目錄
    • base <string> 文件全名。如果pathObject.base 存在稻爬,則 pathObject.extpathObject.name 會被忽略
    • name <string> 文件名字(不帶后綴)
    • ext <string> 文件后綴
  • 返回: <string> 返回完整路徑字符串
path.format({
  dir: '/home/user/dir',
  base: 'file.txt'
});
// 返回: '/home/user/dir/file.txt'

path.format({
  root: '/',
  name: 'file',
  ext: '.txt'
});
// 返回: '/file.txt'

把路徑字符串轉(zhuǎn)換成對象

path.parse() 方法返回一個對象嗜闻,對象的屬性表示 path 的元素。

parse方法跟 format方法正好相反因篇,所以不贅述泞辐。直接看例子:

let pathObj = path.parse('/users/home/aicoder/a.html');
console.dir(pathObj);

// 輸出如下
{ root: '/',
  dir: '/users/home/aicoder',
  base: 'a.html',
  ext: '.html',
  name: 'a' }

連接多個路徑重點

path.join() 方法使用平臺特定的分隔符把全部給定的 path 片段連接到一起,并規(guī)范化生成的路徑竞滓。
長度為零的 path 片段會被忽略咐吼。 如果連接后的路徑字符串是一個長度為零的字符串,則返回 '.'商佑,表示當(dāng)前工作目錄锯茄。

參數(shù)說明:
...paths <string> 一個路徑片段的序列。
返回: <string>

path.join('/foo', 'bar', 'baz/asdf', 'quux', '..');
// 返回: '/foo/bar/baz/asdf'
path.join('/foot', __filename); // __filename是模塊內(nèi)的變量,代表當(dāng)前js文件
// 返回:/foot/xxx.js    

// 以下路徑拼接的方式不推薦:
var strPath = '/foot/' + 'xxx.js';  //雖然跟上面實現(xiàn)的方式一致肌幽,但是不推薦晚碾。

注意:不推薦路徑直接進行字符串拼接,畢竟win和POSIX系統(tǒng)路徑有區(qū)別喂急。

獲取相對路徑

path.relative() 方法返回從 from 到 to 的相對路徑(基于當(dāng)前工作目錄)格嘁。
如果 from 和 to 各自解析到同一路徑(調(diào)用 path.resolve()),則返回一個長度為零的字符串廊移。
如果 from 或 to 傳入了一個長度為零的字符串糕簿,則當(dāng)前工作目錄會被用于代替長度為零的字符串。

語法: path.relative(from, to)
參數(shù):

  • from <string> 求相對路徑的原始路徑狡孔。
  • to <string> 求相對路徑的最終路徑懂诗。
  • 返回: <string> 返回相對于from的 to的相對路徑。
path.relative('/data/orandea/test/aaa', '/data/orandea/impl/bbb');
// 返回: '../../impl/bbb'

智能解析絕對路徑

path.resolve() 方法會把一個路徑或路徑片段的序列解析為一個絕對路徑苗膝。

規(guī)則:
1. 給定的路徑的序列是從右往左被處理的腰耙,后面每個 path 被依次解析伶跷,直到構(gòu)造完成一個絕對路徑佑菩。
2. 如果處理完全部給定的 path 片段后還未生成一個絕對路徑背伴,則當(dāng)前工作目錄會被用上。
3. 生成的路徑是規(guī)范化后的界阁,且末尾的斜杠會被刪除侯繁,除非路徑被解析為根目錄胖喳。
4. 長度為零的 path 片段會被忽略泡躯。
5. 如果沒有傳入 path 片段,則 path.resolve() 會返回當(dāng)前工作目錄的絕對路徑丽焊。
path.resolve('/foo/bar', './baz');
// 返回: '/foo/bar/baz'
path.resolve('/foo/bar', '/tmp/file/');
// 返回: '/tmp/file'
path.resolve('wwwroot', 'static_files/png/', '../gif/image.gif');
// 如果當(dāng)前工作目錄為 /home/myself/node较剃,
// 則返回 '/home/myself/node/wwwroot/static_files/gif/image.gif'

對路徑字符串進行規(guī)范化

path.normalize() 方法會規(guī)范化給定的 path,并解析 '..' 和 '.' 片段技健。
當(dāng)發(fā)現(xiàn)多個連續(xù)的路徑分隔符時(如 POSIX 上的 / 與 Windows 上的 \ 或 /)写穴,它們會被單個的路徑分隔符(POSIX 上是 /,Windows 上是 \)替換雌贱。 末尾的多個分隔符會被保留啊送。
如果 path 是一個長度為零的字符串,則返回 '.'欣孤,表示當(dāng)前工作目錄馋没。

語法: path.normalize(path)

  • path <string> 要進行規(guī)范的路徑字符串
  • 返回: <string> 規(guī)范后的路徑字符串
path.normalize('/foo/bar//baz/asdf/quux/..');
// 返回: '/foo/bar/baz/asdf

// windows 上
path.normalize('C:\\temp\\\\foo\\bar\\..\\');
// 返回: 'C:\\temp\\foo\\'

平臺兼容的分隔符

路徑片段分隔符:

Windows 上是 \
POSIX 上是 /

為了兼容不同平臺,node提供了一個path的輔助屬性path.sep來兼容不同平臺下的路徑片段分隔符降传。

console.log(path.sep);  // POSIX: /     windows:  \

// 在 POSIX 上:
'foo/bar/baz'.split(path.sep);
// 返回: ['foo', 'bar', 'baz']

//在 Windows 上:
'foo\\bar\\baz'.split(path.sep);
// 返回: ['foo', 'bar', 'baz']

路徑分隔符

平臺路徑分隔符是不同的:
Windows 上是 ;
POSIX 上是 :

node也做了兼容處理篷朵,提供了path.delimiter來實現(xiàn)平臺兼容。

例如,我們常見的path環(huán)境變量上做分割處理:

//在 POSIX 上:
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:\Program Files\node\'
process.env.PATH.split(path.delimiter);
// 返回: ['C:\\Windows\\system32', 'C:\\Windows', 'C:\\Program Files\\node\\']

判斷是否是絕對路徑

path.isAbsolute(path)此方法接受一個字符串声旺,返回boolean類型笔链。

// POSIX
path.isAbsolute('/foo/bar'); // true
path.isAbsolute('qux/');     // false
// Windows
path.isAbsolute('C:\\foo\\..'); // true
path.isAbsolute('bar\\baz');    // false

總結(jié)

node的path模塊使用非常簡單,而且老馬簡單看了一下node的源碼腮猖,寫的非常精彩鉴扫,對于多種情況的處理都很恰到好處,推薦大家看node的path模塊源碼: /lib/path.js澈缺。


老馬免費視頻教程

返回教程列表首頁

github地址:https://github.com/malun666/aicoder_node

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末幔妨,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子谍椅,更是在濱河造成了極大的恐慌误堡,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件雏吭,死亡現(xiàn)場離奇詭異锁施,居然都是意外死亡,警方通過查閱死者的電腦和手機杖们,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門悉抵,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人摘完,你說我怎么就攤上這事姥饰。” “怎么了孝治?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵列粪,是天一觀的道長。 經(jīng)常有香客問我谈飒,道長岂座,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任杭措,我火速辦了婚禮费什,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘手素。我一直安慰自己鸳址,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布泉懦。 她就那樣靜靜地躺著稿黍,像睡著了一般。 火紅的嫁衣襯著肌膚如雪祠斧。 梳的紋絲不亂的頭發(fā)上闻察,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天,我揣著相機與錄音,去河邊找鬼辕漂。 笑死呢灶,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的钉嘹。 我是一名探鬼主播鸯乃,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼跋涣!你這毒婦竟也來了缨睡?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤陈辱,失蹤者是張志新(化名)和其女友劉穎奖年,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體沛贪,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡陋守,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了利赋。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片水评。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖媚送,靈堂內(nèi)的尸體忽然破棺而出中燥,到底是詐尸還是另有隱情,我是刑警寧澤塘偎,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布疗涉,位于F島的核電站,受9級特大地震影響式塌,放射性物質(zhì)發(fā)生泄漏博敬。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一峰尝、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧收恢,春花似錦武学、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至驮肉,卻和暖如春熏矿,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工票编, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留褪储,地道東北人。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓慧域,卻偏偏與公主長得像鲤竹,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子昔榴,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,916評論 2 344