1. 程式人生 > >Node.js FS模組方法速查

Node.js FS模組方法速查

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 or Buffers
  • 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()更高效,可能的話,儘量使用前者。

3. 參考

原文地址:https://segmentfault.com/a/1190000017359113