cp无法获取文件状态stat_Node.js从零开始——文件系统
我努力找了找圖,不過清晰度堪憂啊,所以自己做了一張,有點丑不過也就這樣了,哈哈。
今天的內容主要就是 Node.js 的文件系統,畢竟服務器么,也有文件服務器不是?
1 文件系統模塊
這里把文件系統模塊放在前面來說,因為上次的 HTTP 模塊相對簡單,所以放在了最后,但是有關文件操作的模塊通常都比較復雜,為了確保沒接觸過的朋友也能看明白,這次就把它放前面來了。
fs 模塊提供了許多非常實用的函數來訪問文件系統并與文件系統進行交互,它作為 Node.js 核心的組成部分,無需安裝,可以通過簡單地引用來使用它:
const一旦這樣做,就可以訪問其所有的方法,包括:
- fs.access():檢查文件是否存在,以及 Node.js 是否有權限訪問
- fs.appendFile():追加數據到文件,如果文件不存在,則創建文件
- fs.chmod(): 更改文件(通過傳入的文件名指定)的權限,相關方法:fs.lchmod()、fs.fchmod()
- fs.chown():更改文件(通過傳入的文件名指定)的所有者和群組,相關方法:fs.fchown()、fs.lchown()
- fs.close():關閉文件描述符
- fs.copyFile():拷貝文件
- fs.createReadStream():創建可讀的文件流
- fs.createWriteStream():創建可寫的文件流
- fs.link():新建指向文件的硬鏈接
- fs.mkdir():新建文件夾
- fs.mkdtemp():創建臨時目錄
- fs.open():設置文件模式
- fs.readdir():讀取目錄的內容
- fs.readFile():讀取文件的內容,相關方法:fs.read()
- fs.readlink():讀取符號鏈接的值
- fs.realpath():將相對的文件路徑指針(.、..)解析為完整的路徑
- fs.rename():重命名文件或文件夾
- fs.rmdir():刪除文件夾
- fs.stat():返回文件(通過傳入的文件名指定)的狀態,相關方法:fs.fstat()、fs.lstat()
- fs.symlink():新建文件的符號鏈接
- fs.truncate():將傳遞的文件名標識的文件截斷為指定的長度,相關方法:fs.ftruncate()
- fs.unlink():刪除文件或符號鏈接
- fs.unwatchFile():停止監視文件上的更改
- fs.utimes():更改文件(通過傳入的文件名指定)的時間戳,相關方法:fs.futimes()
- fs.watchFile():開始監視文件上的更改,相關方法:fs.watch()
- fs.writeFile():將數據寫入文件,相關方法:fs.write()
關于 fs 模塊的特殊之處是,所有的方法默認情況下都是異步的,但是通過加上 Sync 后綴也可以同步地工作。
例如:
- fs.rename()
- fs.renameSync()
- fs.write()
- fs.writeSync()
這在應用程序流程中會產生巨大的差異。
從 Node.js 10 后,fs 也包括了對 Promise API 的支持,可以參考 FS Promise API。例如,試驗一下 fs.rename() 方法, 異步的 API 會與回調一起使用:
const同步的 API 則可以這樣使用,并使用 try/catch 塊來處理錯誤:
const此處的主要區別在于,在第二個示例中,腳本的執行會阻塞(!!很重要,有的時候反而是解決一些問題的思路),直到文件操作成功。
2 在 Node.js 中使用文件描述符
在與位于文件系統中的文件進行交互之前,需要先獲取文件的描述符。
文件描述符是使用 fs 模塊提供的 open() 方法打開文件后返回的:
const注意,將 r 作為 fs.open() 調用的第二個參數,意味著打開文件用于讀取。
當然如果僅僅是把文件描述符單獨打印出來,其實就是個沒什么意義的字符,比如:
其他常用的標志有:
- r+ 打開文件用于讀寫
- w+ 打開文件用于讀寫,將流定位到文件的開頭;如果文件不存在則創建文件
- a 打開文件用于寫入,將流定位到文件的末尾;如果文件不存在則創建文件
- a+ 打開文件用于讀寫,將流定位到文件的末尾;如果文件不存在則創建文件
也可以使用 fs.openSync 方法打開文件,該方法會返回文件描述符(而不是在回調中提供):
const一旦獲得文件描述符,就可以以任何方式執行所有需要它的操作,例如調用 fs.open() 以及許多與文件系統交互的其他操作。
3 文件屬性
每個文件都帶有一組詳細信息,可以使用 Node.js 進行檢查,具體地說,使用 fs 模塊提供的 stat() 方法。
調用時傳入文件的路徑,一旦 Node.js 獲得文件的詳細信息,則會調用傳入的回調函數,并帶上兩個參數:錯誤消息和文件屬性:
constNode.js 也提供了同步的方法,該方法會阻塞線程,直到文件屬性準備就緒為止:
const文件的信息包含在屬性變量中,可以通過屬性提取很多信息,包括:
- 使用 stats.isFile() 和 stats.isDirectory() 判斷文件是否目錄或文件
- 使用 stats.isSymbolicLink() 判斷文件是否符號鏈接
- 使用 stats.size 獲取文件的大小(以字節為單位)
還有其他一些高級的方法,但是在日常編程中會使用的大部分是這些:
const當然這里為了能夠輸出結果,我直接打印在了控制臺,可以直接看到結果。
4 文件路徑
系統中的每個文件都有路徑。
在 Linux 和 macOS 上,路徑可能類似于:
/users/joe/file.txt在 Windows 上則有所不同,具有類似以下的結構:
C:usersjoefile.txt當在應用程序中使用路徑時需要注意,因為必須考慮到這種差異;不過好在 PowerShell 的出現使得統一使用類 Unix 路徑成為可能,不過這個特指相對路徑,如果是絕對路徑,那么 Windows 還是必須遵從 [盤符]:[路徑] 的方式。
可以使用以下方式將此模塊引入到文件中:
const現在可以開始使用其方法了。
4.1 從路徑中獲取信息
給定一個路徑,可以使用以下方法從其中提取信息:
- dirname:獲取文件的父文件夾
- basename:獲取文件名部分
- extname:獲取文件的擴展名
例如:
可以通過為 basename 指定第二個參數來獲取不帶擴展名的文件名:
4.2 使用路徑
可以使用 path.join() 連接路徑的兩個或多個片段:
因為我用的是 Windows 系統,所以 / 或自動轉換為 ;如果是類 Unix 系統,就是正常的 /可以使用 path.resolve() 獲得相對路徑的絕對路徑計算:
同上例在此示例中,Node.js 只是簡單地將 /server.js 附加到當前工作目錄,如果指定第二個文件夾參數,則 resolve 會使用第一個作為第二個的基礎:
如果第一個參數以斜杠開頭,則表示它是絕對路徑:
path.normalize() 是另一個有用的函數,當包含諸如 .、.. 或雙斜杠之類的相對說明符時,其會嘗試計算實際的路徑:
解析和規范化都不會檢查路徑是否存在。 其只是根據獲得的信息來計算路徑。
5 讀取文件
在 Node.js 中讀取文件最簡單的方式是使用 fs.readFile() 方法,向其傳入文件路徑、編碼、以及會帶上文件數據(以及錯誤)進行調用的回調函數:
另外,也可以使用同步的版本 fs.readFileSync():
constfs.readFile() 和 fs.readFileSync() 都會在返回數據之前將文件的全部內容讀取到內存中。
這意味著大文件會對內存的消耗和程序執行的速度產生重大的影響。
在這種情況下,更好的選擇是使用流來讀取文件的內容。
6 寫入文件
在 Node.js 中寫入文件最簡單的方式是使用 fs.writeFile() API。
例如:
另外,也可以使用同步的版本 fs.writeFileSync():
const默認情況下,此 API 會替換文件的內容(如果文件已經存在)。
可以通過指定標志來修改默認的行為:
fs可能會使用的標志有:
- r+ 打開文件用于讀寫
- w+ 打開文件用于讀寫,將流定位到文件的開頭;如果文件不存在則創建文件
- a 打開文件用于寫入,將流定位到文件的末尾;如果文件不存在則創建文件
- a+ 打開文件用于讀寫,將流定位到文件的末尾;如果文件不存在則創建文件
(可以在 http://nodejs.cn/api/fs.html#fs_file_system_flags 中查看更多標志)
6.1 追加到文件
將內容追加到文件末尾的便捷方法是 fs.appendFile()(及其對應的 fs.appendFileSync()):
6.2 使用流
所有這些方法都是在將全部內容寫入文件之后才會將控制權返回給程序(在異步的版本中,這意味著執行回調)。
在這種情況下,更好的選擇是使用流寫入文件的內容。
7 處理文件夾
Node.js 的 fs 核心模塊提供了許多便捷的方法用于處理文件夾。
7.1 檢查文件夾是否存在
使用 fs.access() 檢查文件夾是否存在以及 Node.js 是否具有訪問權限。
7.2 創建新的文件夾
使用 fs.mkdir() 或 fs.mkdirSync() 可以創建新的文件夾:
7.3 讀取目錄的內容
使用 fs.readdir() 或 fs.readdirSync() 可以讀取目錄的內容。
這段代碼會讀取文件夾的內容(全部的文件和子文件夾),并返回它們的相對路徑,因為同步方式比較簡單,不需要太多代碼,所以這個例子是同步的:
可以獲取完整的路徑:
當然在 Windows 上面又變成了這樣,我忍也可以過濾結果以僅返回文件(排除文件夾):
7.4 重命名文件夾
使用 fs.rename() 或 fs.renameSync() 可以重命名文件或者文件夾,第一個參數是當前的路徑,第二個參數是新的路徑:
文件重命名文件夾重命名fs.renameSync() 是同步的版本:
const7.5 刪除文件夾
使用 fs.rmdir() 或 fs.rmdirSync() 可以刪除文件夾。
刪除包含內容的文件夾可能會更復雜,因為這個功能不能同時刪除文件,所以必須先刪除文件夾內的所有文件,才能實現刪除文件夾的操作。
在這種情況下,最好安裝 fs-extra 模塊,該模塊非常受歡迎且維護良好,它是 fs 模塊的直接替代品,在其之上提供了更多的功能。
在此示例中,需要的是 remove() 方法。
首先使用以下命令安裝該模塊:
npm install -g fs-extra并像這樣使用它:
也可以與 promise 一起使用:
fs或使用 async/await:
async8 路徑模塊
因為前面用到了路徑模塊,所以也簡單的介紹一下這個模塊。
path 模塊提供了許多非常實用的函數來訪問文件系統并與文件系統進行交互,同樣作為 Node.js 核心的組成部分,也是無需安裝的,可以通過簡單地引用來使用它:
const該模塊提供了 path.sep(作為路徑段分隔符,在 Windows 上是 ,在 Linux/macOS 上是 /)和 path.delimiter(作為路徑定界符,在 Windows 上是 ;,在 Linux/macOS 上是 :)。
還有一下這些 path 方法:
8.1 path.basename()
返回路徑的最后一部分。 第二個參數可以過濾掉文件的擴展名:
8.2 path.dirname()
返回路徑的目錄部分:
8.3 path.extname()
返回路徑的擴展名部分:
8.4 path.isAbsolute()
如果是絕對路徑,則返回 true:
8.5 path.join()
連接路徑的兩個或多個部分:
8.6 path.normalize()
當包含類似 .、.. 或雙斜杠等相對的說明符時,則嘗試計算實際的路徑:
8.7 path.parse()
解析對象的路徑為組成其的片段:
- root:根路徑
- dir:從根路徑開始的文件夾路徑
- base:文件名 + 擴展名
- name:文件名
- ext:文件擴展名
例如:
require結果是:
8.8 path.relative()
接受 2 個路徑作為參數;基于當前工作目錄,返回從第一個路徑到第二個路徑的相對路徑。
例如:
8.9 path.resolve()
可以使用 path.resolve() 獲得相對路徑的絕對路徑計算:
通過指定第二個參數,resolve 會使用第一個參數作為第二個參數的基準:
如果第一個參數以斜杠開頭,則表示它是絕對路徑:
當然 Windows 是無法省略掉盤符的,所以……不像類 Unix 系統是直接到了根路徑。
總結
以上是生活随笔為你收集整理的cp无法获取文件状态stat_Node.js从零开始——文件系统的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 什么是云仓
- 下一篇: java信息管理系统总结_java实现科