Node入門教程(8)第六章:path 模塊詳解
path 模塊詳解
path
模塊提供了一些工具函數,用於處理文件與目錄的路徑。由於windows和其他系統之間路徑不統一,path
模塊還專門做了相關處理,屏蔽了彼此之間的差異。
可移植操作系統接口(POSIX)
可移植操作系統接口(英語:Portable Operating System Interface,縮寫為POSIX),是IEEE為要在各種UNIX操作系統上運行軟件,而定義API的一系列互相關聯的標準的總稱,其正式稱呼為IEEE Std 1003,而國際標準名稱為ISO/IEC 9945。此標準源於一個大約開始於1985年的項目。POSIX這個名稱是由理查德·斯托曼應IEEE的要求而提議的一個易於記憶的名稱。它基本上是Portable Operating System Interface(可移植操作系統接口)的縮寫,而X則表明其對Unix API的傳承。
Linux基本上逐步實現了POSIX兼容,但並沒有參加正式的POSIX認證。
微軟的Windows NT聲稱部分實現了POSIX標準。
當前的POSIX主要分為四個部分:Base Definitions、System Interfaces、Shell and Utilities和Rationale。
綜述:目前主流的類Unix操作系統:Unix、Linux都會兼容POSIX的標準,而Windows只是部分實行了POSIX標準,所以後面我們說POSIX系統是指類Unix系統
windows系統和類Unix系統的路徑的區別
目錄結構的區別
可能大家比較熟悉windows資源管理系統,windows是分不同的磁盤,然後磁盤下面都是樹狀結構的文件和文件夾。
而類Unix(Unix、Linux)系統中是不分盤符的,只有一個根目錄 /
, 都是都是這個下面的子目錄或者文件,當然也是樹狀的機構。
Linux的目錄結構
[圖片上傳失敗...(image-233704-1522805165775)];
路徑的區別
除了目錄結構有區別外,路徑也是有區別的。windows是用反斜杠\
分割目錄或者文件的,而在類Unix的系統中是用的/
。
windows的路徑: C:\temp\myfile.html
類Unix的路徑: /tmp/myfile.html
path模塊獲取路徑中的文件名
語法:path.basename(path[, ext])
參數:
- 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(linuxPath);
console.log(winName);
console.log(path.basename(linuxPath, ‘.html‘)); // => abc,去掉後綴輸出文件名
// 輸出結果
abc.html
abc.html
abc
node提供了win32和posix兼容的api
默認情況下,node會根據不同的系統做相關兼容處理,力保輸出的結果在不同平臺下是一致的,但是某些情況下還是不能完美的兼容所有的情況。所以,node提供了win32
和posix
各自對應path的所有的api。也就是說:path
模塊的api都可以通過path.win32
或者 path.posix
調用。
要想在任何操作系統上處理 Windows 文件路徑時獲得一致的結果,可以使用 path.win32
path.win32.basename(‘C:\\temp\\myfile.html‘);
// 返回: ‘myfile.html‘
要想在任何操作系統上處理 POSIX 文件路徑時獲得一致的結果,可以使用 path.posix
path.posix.basename(‘/tmp/myfile.html‘);
// 返回: ‘myfile.html‘
其他api也是一致的,不再贅述。
獲取路徑的文件夾
path.dirname()
方法返回一個 path 的目錄名。
語法: path.dirname(path)
參數:
path <string>
,要返回路徑的變量- 返回:
<string>
path.dirname(‘/foo/bar/baz/asdf/quux‘);
// 返回: ‘/foo/bar/baz/asdf‘
獲取路徑的擴展名
path.extname()
方法返回 path 的擴展名,即從 path 的最後一部分中的最後一個 .(句號)字符到字符串結束。
如果 path 的最後一部分沒有 .
或 path 的文件名的第一個字符是 .
,則返回一個空字符串。
語法: path.extname(path)
- 參數:
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> 要轉換成路徑字符串的設置對象
- dir <string> 所在目錄,提供了 pathObject.dir,則 pathObject.root 會被忽略
- root <string> 根目錄
- base <string> 文件全名。如果
pathObject.base
存在,則pathObject.ext
和pathObject.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‘
把路徑字符串轉換成對象
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 片段連接到一起,並規範化生成的路徑。
長度為零的 path 片段會被忽略。 如果連接後的路徑字符串是一個長度為零的字符串,則返回 ‘.‘,表示當前工作目錄。
參數說明:...paths <string>
一個路徑片段的序列。
返回: <string>
path.join(‘/foo‘, ‘bar‘, ‘baz/asdf‘, ‘quux‘, ‘..‘);
// 返回: ‘/foo/bar/baz/asdf‘
path.join(‘/foot‘, __filename); // __filename是模塊內的變量,代表當前js文件
// 返回:/foot/xxx.js
// 以下路徑拼接的方式不推薦:
var strPath = ‘/foot/‘ + ‘xxx.js‘; //雖然跟上面實現的方式一致,但是不推薦。
註意:不推薦路徑直接進行字符串拼接,畢竟win和POSIX系統路徑有區別。
獲取相對路徑
path.relative() 方法返回從 from 到 to 的相對路徑(基於當前工作目錄)。
如果 from 和 to 各自解析到同一路徑(調用 path.resolve()),則返回一個長度為零的字符串。
如果 from 或 to 傳入了一個長度為零的字符串,則當前工作目錄會被用於代替長度為零的字符串。
語法: path.relative(from, to)
參數:
- from <string> 求相對路徑的原始路徑。
- to <string> 求相對路徑的最終路徑。
- 返回: <string> 返回相對於from的 to的相對路徑。
path.relative(‘/data/orandea/test/aaa‘, ‘/data/orandea/impl/bbb‘);
// 返回: ‘../../impl/bbb‘
智能解析絕對路徑
path.resolve() 方法會把一個路徑或路徑片段的序列解析為一個絕對路徑。
規則:
1. 給定的路徑的序列是從右往左被處理的,後面每個 path 被依次解析,直到構造完成一個絕對路徑。
2. 如果處理完全部給定的 path 片段後還未生成一個絕對路徑,則當前工作目錄會被用上。
3. 生成的路徑是規範化後的,且末尾的斜杠會被刪除,除非路徑被解析為根目錄。
4. 長度為零的 path 片段會被忽略。
5. 如果沒有傳入 path 片段,則 path.resolve() 會返回當前工作目錄的絕對路徑。
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‘);
// 如果當前工作目錄為 /home/myself/node,
// 則返回 ‘/home/myself/node/wwwroot/static_files/gif/image.gif‘
對路徑字符串進行規範化
path.normalize() 方法會規範化給定的 path,並解析 ‘..‘ 和 ‘.‘ 片段。
當發現多個連續的路徑分隔符時(如 POSIX 上的 / 與 Windows 上的 \ 或 /),它們會被單個的路徑分隔符(POSIX 上是 /,Windows 上是 \)替換。 末尾的多個分隔符會被保留。
如果 path 是一個長度為零的字符串,則返回 ‘.‘,表示當前工作目錄。
語法: path.normalize(path)
- path <string> 要進行規範的路徑字符串
- 返回: <string> 規範後的路徑字符串
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
來實現平臺兼容。
例如,我們常見的path環境變量上做分割處理:
//在 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
總結
node的path模塊使用非常簡單,而且老馬簡單看了一下node的源碼,寫的非常精彩,對於多種情況的處理都很恰到好處,推薦大家看node的path模塊源碼: /lib/path.js。
老馬免費視頻教程
返回教程列表首頁
github地址:https://github.com/malun666/aicoder_node
Node入門教程(8)第六章:path 模塊詳解