1. File System
- 所有文件操作提供
同步
和異步
的兩種方式,本筆記只記錄異步的API - 異步方式其最後一個參數是回調函數。回調函數的第一個參數往往是錯誤對象,如果沒有發生參數,那麼第一個參數可能是
null
或者undefinded
。 - 同步函數可以使用
try catch
捕獲異常 - 多個異步函數在同一層次執行,是
無法保證順序
的。最好將一個函數放在另一個函數的回調函數中去執行。這種回調的嵌套層次一旦過深,就會造成回調地獄
- 一般情況下,
非常不建議使用同步
的fs方法,因爲同步的方法會阻斷其他事情,直到fs方法完成。
1.1. 文件路徑
-
filepaths目前支持4中
string
Buffer
URL Object
- 以
file:
開頭的協議
- string 路徑會被解釋爲utf-8格式,可以使用相對路徑和絕對路徑,相對路徑是當前工作路徑,可以從
process.cwd()
獲取當前工作路徑。
1.2. 文件描述符
- 操作系統會限制文件描述符的數量
- 忘記關閉文件可能導致
內存泄露
或者程序崩潰
- 任何文件描述符都支持寫操作
- 如果文件描述符的類型是文件,那麼它不會自動關閉
- 寫操作會從文件的開頭,而不會覆蓋之後的內容。舉例:文件內容是
Hello World
, 如果在寫入'Aloha',那麼文件的內容是Aloha World
,而不是'Aloha'.
1.3. 線程池使用
fs所有的api,除了那些同步的api和fs.FSWatcher(), 基本上都使用libuv的線程池。在有些應用程序上,這個可能導致非常糟糕的性能表現。libuv的線程池有固定的大小,默認只有4個,可以通過設置環境變量UV_THREADPOOL_SIZE
去增加libuv的線程的數量。
1.4. Class: fs.Dirent 判斷文件類型
- 當
fs.readdir()
或者fs.readdirSync()
被調用,並且參數withFileTypes
是true
, 那麼返回結果就是fs.Dirent objects
, 而不是strings
orBuffers
-
dirent方法
- dirent.isBlockDevice()
- dirent.isCharacterDevice()
- dirent.isDirectory()
- dirent.isFIFO()
- dirent.isFile()
- dirent.isSocket()
- dirent.isSymbolicLink()
- dirent.name
1.5. Class: fs.FSWatcher 文件變動監控
來自 fs.watch()
-
Event
change
close
error
- watcher.close()
注意:某些系統可能不會返回filename。如果encoding參數是buffer,那麼文件名是以buffer的形式返回,默認文件名是utf-8格式的字符串。
fs.watch('./tmp', { encoding: 'buffer' }, (eventType, filename) => {
if (filename) {
console.log(filename);
// Prints: <Buffer ...>
}
});
1.6. Class: fs.ReadStream 可讀流
來自fs.createReadStream()
-
Event
close
open
-
ready
第一次觸發是在open事件之後
- readStream.bytesRead
- readStream.path
- readStream.pending
1.7. Class: fs.Stats 獲取文件信息
來自 fs.stat()
, fs.lstat()
and fs.fstat()
以及他們的同步版本。
- stats.isBlockDevice()
- stats.isCharacterDevice()
- stats.isDirectory()
- stats.isFIFO()
- stats.isFile()
- stats.isSocket()
- stats.isSymbolicLink()
Stats {
dev: 2114,
ino: 48064969,
mode: 33188,
nlink: 1,
uid: 85,
gid: 100,
rdev: 0,
size: 527,
blksize: 4096,
blocks: 8,
atimeMs: 1318289051000.1,
mtimeMs: 1318289051000.1,
ctimeMs: 1318289051000.1,
birthtimeMs: 1318289051000.1,
atime: Mon, 10 Oct 2011 23:24:11 GMT,
mtime: Mon, 10 Oct 2011 23:24:11 GMT,
ctime: Mon, 10 Oct 2011 23:24:11 GMT,
birthtime: Mon, 10 Oct 2011 23:24:11 GMT }
1.8. Class: fs.WriteStream 可寫流
-
Event
- close
- open
- ready
- writeStream.bytesWritten
- writeStream.path
- writeStream.pending
2. 常用方法
測試
-
訪問權限測試
fs.access(path[, mode], callback) 測試是否可以訪問某個路徑。不建議fs.open(), fs.readFile() or fs.writeFile()調用前,調用fs.access去檢查
-
-
測試路徑是否存在
fs.exists(path, callback), 不建議fs.open(), fs.readFile() or fs.writeFile()調用前,調用fs.exists去檢測文件是否存在 -
流操作
-
創建可讀流
fs.createReadStream(path[, options]) -
創建可寫流
fs.createWriteStream(path[, options])
-
-
文件夾操作
-
創建文件夾
fs.mkdir(path[, options], callback) -
刪除目錄
fs.rmdir(path, callback) -
創建臨時文件夾
fs.mkdtemp(prefix[, options], callback) -
讀取文件夾
fs.readdir(path[, options], callback)
-
-
文件操作
-
打開文件
fs.open(path[, flags[, mode]], callback) -
讀取文件
fs.read(fd, buffer, offset, length, position, callback) -
讀取文件
fs.readFile(path[, options], callback) -
重命名文件
fs.rename(oldPath, newPath, callback) -
讀取文件信息
fs.stat(path[, options], callback) -
刪除文件
fs.unlink(path, callback) -
停止監控文件
fs.unwatchFile(filename[, listener]) -
修改時間
fs.utimes(path, atime, mtime, callback) -
監控文件變化
fs.watch(filename, options) -
關閉文件
fs.close(fd, callback) -
追加文件
fs.appendFile(path, data[, options], callback) -
改變文件模式
fs.chmod(path, mode, callback) -
改變文件所屬
fs.chown(path, uid, gid, callback) -
複製文件
fs.copyFile(fs.copyFile(src, dest[, flags], callback)) -
寫文件
fs.write(fd, buffer[, offset[, length[, position]]], callback) -
寫文件
fs.write(fd, string[, position[, encoding]], callback) -
寫文件
fs.writeFile(file, data[, options], callback)
-
-
其他
-
fs常量
fs.constants
-
-
注意事項
-
fs.watch
並不是百分百跨平臺。例如它的recursive
參數僅支持macOS和windows。fs.watch的底層通知機制在不同平臺上的實現是不同的,如果底層不支持某個特性,那麼fs.watch也是不能支持的。另外回調函數中的filename參數,也是不保證一定存在。 -
fs.watch()
比fs.watchFile()
更高效,可能的話,儘量使用前者。
-