Node.js 檔系統

Node.js 提供一組類似 UNIX(POSIX)標準的檔操作API。 Node 導入檔系統模組(fs)語法如下所示:

var fs = require("fs")

非同步和同步

Node.js 檔系統(fs 模組)模組中的方法均有非同步和同步版本,例如讀取檔內容的函數有非同步的 fs.readFile() 和同步的 fs.readFileSync()。

非同步的方法函數最後一個參數為回調函數,回調函數的第一個參數包含了錯誤資訊(error)。

建議大家使用非同步方法,比起同步,非同步方法性能更高,速度更快,而且沒有阻塞。

實例

創建 input.txt 檔,內容如下:

IT研修官網地址:www.xuhuhu.com
檔讀取實例

創建 file.js 檔, 代碼如下:

var fs = require("fs");

// 非同步讀取

fs.readFile('input.txt', function (err, data) {
   if (err) {
       return console.error(err);
   }
   console.log("非同步讀取: " + data.toString());
});

// 同步讀取

var data = fs.readFileSync('input.txt');
console.log("同步讀取: " + data.toString());

console.log("程式執行完畢。");

以上代碼執行結果如下:

$ node file.js
同步讀取: IT研修官網地址:www.xuhuhu.com
檔讀取實例


程式執行完畢。

非同步讀取: IT研修官網地址:www.xuhuhu.com
檔讀取實例

接下來,讓我們來具體瞭解下 Node.js 檔系統的方法。


打開檔

語法

以下為在非同步模式下打開檔的語法格式:

fs.open(path, flags[, mode], callback)

參數

參數使用說明如下:

  • path - 檔的路徑。

  • flags - 檔打開的行為。具體值詳見下文。

  • mode - 設置檔模式(許可權),檔創建默認許可權為 0666(可讀,可寫)。

  • callback - 回調函數,帶有兩個參數如:callback(err, fd)。

flags 參數可以是以下值:

Flag描述
r以讀取模式打開檔。如果檔不存在拋出異常。
r+ 以讀寫模式打開檔。如果檔不存在拋出異常。
rs以同步的方式讀取檔。
rs+以同步的方式讀取和寫入檔。
w以寫入模式打開檔,如果檔不存在則創建。
wx類似 'w',但是如果檔路徑存在,則檔寫入失敗。
w+以讀寫模式打開檔,如果檔不存在則創建。
wx+類似 'w+', 但是如果檔路徑存在,則檔讀寫失敗。
a以追加模式打開檔,如果檔不存在則創建。
ax類似 'a', 但是如果檔路徑存在,則檔追加失敗。
a+以讀取追加模式打開檔,如果檔不存在則創建。
ax+類似 'a+', 但是如果檔路徑存在,則檔讀取追加失敗。

實例

接下來我們創建 file.js 檔,並打開 input.txt 檔進行讀寫,代碼如下所示:

var fs = require("fs");

// 非同步打開檔
console.log("準備打開檔!");
fs.open('input.txt', 'r+', function(err, fd) {
   if (err) {
       return console.error(err);
   }
  console.log("檔打開成功!");
});

以上代碼執行結果如下:

$ node file.js
準備打開檔!
檔打開成功!

獲取檔資訊

語法

以下為通過非同步模式獲取檔資訊的語法格式:

fs.stat(path, callback)

參數

參數使用說明如下:

  • path - 檔路徑。

  • callback - 回調函數,帶有兩個參數如:(err, stats), stats 是 fs.Stats 對象。

fs.stat(path)執行後,會將stats類的實例返回給其回調函數。可以通過stats類中的提供方法判斷檔的相關屬性。例如判斷是否為檔:

var fs = require('fs');

fs.stat('/Users/liuht/code/itbilu/demo/fs.js', function (err, stats) {
    console.log(stats.isFile());         //true
})

stats類中的方法有:

方法描述
stats.isFile()如果是檔返回 true,否則返回 false。
stats.isDirectory()如果是目錄返回 true,否則返回 false。
stats.isBlockDevice()如果是塊設備返回 true,否則返回 false。
stats.isCharacterDevice()如果是字元設備返回 true,否則返回 false。
stats.isSymbolicLink()如果是軟鏈接返回 true,否則返回 false。
stats.isFIFO()如果是FIFO,返回true,否則返回 false。FIFO是UNIX中的一種特殊類型的命令管道。
stats.isSocket()如果是 Socket 返回 true,否則返回 false。

實例

接下來我們創建 file.js 檔,代碼如下所示:

var fs = require("fs");

console.log("準備打開檔!");
fs.stat('input.txt', function (err, stats) {
   if (err) {
       return console.error(err);
   }
   console.log(stats);
   console.log("讀取檔資訊成功!");

   // 檢測檔類型

   console.log("是否為檔(isFile) ? " + stats.isFile());
   console.log("是否為目錄(isDirectory) ? " + stats.isDirectory());
});

以上代碼執行結果如下:

$ node file.js
準備打開檔!
{ dev: 16777220,
  mode: 33188,
  nlink: 1,
  uid: 501,
  gid: 20,
  rdev: 0,
  blksize: 4096,
  ino: 40333161,
  size: 61,
  blocks: 8,
  atime: Mon Sep 07 2015 17:43:55 GMT+0800 (CST),
  mtime: Mon Sep 07 2015 17:22:35 GMT+0800 (CST),
  ctime: Mon Sep 07 2015 17:22:35 GMT+0800 (CST) }
讀取檔資訊成功!

是否為檔(isFile) ? true
是否為目錄(isDirectory) ? false

寫入檔

語法

以下為非同步模式下寫入檔的語法格式:

fs.writeFile(file, data[, options], callback)

writeFile 直接打開檔默認是 w 模式,所以如果檔存在,該方法寫入的內容會覆蓋舊的檔內容。

參數

參數使用說明如下:

  • file - 檔案名或檔描述符。

  • data - 要寫入檔的數據,可以是 String(字串) 或 Buffer(緩衝) 對象。

  • options - 該參數是一個對象,包含 {encoding, mode, flag}。默認編碼為 utf8, 模式為 0666 , flag 為 'w'

  • callback - 回調函數,回調函數只包含錯誤資訊參數(err),在寫入失敗時返回。

實例

接下來我們創建 file.js 檔,代碼如下所示:

var fs = require("fs");

console.log("準備寫入檔");
fs.writeFile('input.txt', '我是通 過fs.writeFile 寫入檔的內容',  function(err) {
   if (err) {
       return console.error(err);
   }
   console.log("數據寫入成功!");
   console.log("--------我是分割線-------------")
   console.log("讀取寫入的數據!");
   fs.readFile('input.txt', function (err, data) {
      if (err) {
         return console.error(err);
      }
      console.log("非同步讀取檔數據: " + data.toString());
   });
});

以上代碼執行結果如下:

$ node file.js
準備寫入檔

數據寫入成功!

--------我是分割線-------------
讀取寫入的數據!

非同步讀取檔數據: 我是通 過fs.writeFile 寫入檔的內容

讀取檔

語法

以下為非同步模式下讀取檔的語法格式:

fs.read(fd, buffer, offset, length, position, callback)

該方法使用了檔描述符來讀取檔。

參數

參數使用說明如下:

  • fd - 通過 fs.open() 方法返回的檔描述符。

  • buffer - 數據寫入的緩衝區。

  • offset - 緩衝區寫入的寫入偏移量。

  • length - 要從檔中讀取的位元組數。

  • position - 檔讀取的起始位置,如果 position 的值為 null,則會從當前檔指針的位置讀取。

  • callback - 回調函數,有三個參數err, bytesRead, buffer,err 為錯誤資訊, bytesRead 表示讀取的位元組數,buffer 為緩衝區對象。

實例

input.txt 檔內容為:

IT研修官網地址:www.xuhuhu.com

接下來我們創建 file.js 檔,代碼如下所示:

var fs = require("fs");
var buf = new Buffer.alloc(1024);

console.log("準備打開已存在的檔!");
fs.open('input.txt', 'r+', function(err, fd) {
   if (err) {
       return console.error(err);
   }
   console.log("檔打開成功!");
   console.log("準備讀取檔:");
   fs.read(fd, buf, 0, buf.length, 0, function(err, bytes){
      if (err){
         console.log(err);
      }
      console.log(bytes + "  位元組被讀取");

      // 僅輸出讀取的位元組

      if(bytes > 0){
         console.log(buf.slice(0, bytes).toString());
      }
   });
});

以上代碼執行結果如下:

$ node file.js
準備打開已存在的檔!
檔打開成功!
準備讀取檔:

42  位元組被讀取

IT研修官網地址:www.xuhuhu.com

關閉檔

語法

以下為非同步模式下關閉檔的語法格式:

fs.close(fd, callback)

該方法使用了檔描述符來讀取檔。

參數

參數使用說明如下:

  • fd - 通過 fs.open() 方法返回的檔描述符。

  • callback - 回調函數,沒有參數。

實例

input.txt 檔內容為:

IT研修官網地址:www.xuhuhu.com

接下來我們創建 file.js 檔,代碼如下所示:

var fs = require("fs");
var buf = new Buffer.alloc(1024);

console.log("準備打開檔!");
fs.open('input.txt', 'r+', function(err, fd) {
   if (err) {
       return console.error(err);
   }
   console.log("檔打開成功!");
   console.log("準備讀取檔!");
   fs.read(fd, buf, 0, buf.length, 0, function(err, bytes){
      if (err){
         console.log(err);
      }

      // 僅輸出讀取的位元組

      if(bytes > 0){
         console.log(buf.slice(0, bytes).toString());
      }

      // 關閉檔

      fs.close(fd, function(err){
         if (err){
            console.log(err);
         }
         console.log("檔關閉成功");
      });
   });
});

以上代碼執行結果如下:

$ node file.js
準備打開檔!
檔打開成功!
準備讀取檔!

IT研修官網地址:www.xuhuhu.com
檔關閉成功


截取檔

語法

以下為非同步模式下截取檔的語法格式:

fs.ftruncate(fd, len, callback)

該方法使用了檔描述符來讀取檔。

參數

參數使用說明如下:

  • fd - 通過 fs.open() 方法返回的檔描述符。

  • len - 檔內容截取的長度。

  • callback - 回調函數,沒有參數。

實例

input.txt 檔內容為:

site:www.xuhuhu.com

接下來我們創建 file.js 檔,代碼如下所示:

var fs = require("fs");
var buf = new Buffer.alloc(1024);

console.log("準備打開檔!");
fs.open('input.txt', 'r+', function(err, fd) {
   if (err) {
       return console.error(err);
   }
   console.log("檔打開成功!");
   console.log("截取10位元組內的檔內容,超出部分將被去除。");

   // 截取檔

   fs.ftruncate(fd, 10, function(err){
      if (err){
         console.log(err);
      }
      console.log("檔截取成功。");
      console.log("讀取相同的檔");
      fs.read(fd, buf, 0, buf.length, 0, function(err, bytes){
         if (err){
            console.log(err);
         }

         // 僅輸出讀取的位元組

         if(bytes > 0){
            console.log(buf.slice(0, bytes).toString());
         }

         // 關閉檔

         fs.close(fd, function(err){
            if (err){
               console.log(err);
            }
            console.log("檔關閉成功!");
         });
      });
   });
});

以上代碼執行結果如下:

$ node file.js
準備打開檔!
檔打開成功!
截取10位元組內的檔內容,超出部分將被去除。

檔截取成功。

讀取相同的檔

site:www.r
檔關閉成功


刪除檔

語法

以下為刪除檔的語法格式:

fs.unlink(path, callback)

參數

參數使用說明如下:

  • path - 檔路徑。

  • callback - 回調函數,沒有參數。

實例

input.txt 檔內容為:

site:www.xuhuhu.com

接下來我們創建 file.js 檔,代碼如下所示:

var fs = require("fs");

console.log("準備刪除檔!");
fs.unlink('input.txt', function(err) {
   if (err) {
       return console.error(err);
   }
   console.log("檔刪除成功!");
});

以上代碼執行結果如下:

$ node file.js
準備刪除檔!
檔刪除成功!

再去查看 input.txt 檔,發現已經不存在了。


創建目錄

語法

以下為創建目錄的語法格式:

fs.mkdir(path[, options], callback)

參數

參數使用說明如下:

  • path - 檔路徑。

  • options 參數可以是:

    • recursive - 是否以遞歸的方式創建目錄,默認為 false。
    • mode - 設置目錄許可權,默認為 0777。
  • callback - 回調函數,沒有參數。

實例

接下來我們創建 file.js 檔,代碼如下所示:

var fs = require("fs");
// tmp 目錄必須存在
console.log("創建目錄 /tmp/test/");
fs.mkdir("/tmp/test/",function(err){
   if (err) {
       return console.error(err);
   }
   console.log("目錄創建成功。");
});

以上代碼執行結果如下:

$ node file.js
創建目錄 /tmp/test/
目錄創建成功。

可以添加 recursive: true 參數,不管創建的目錄 /tmp 和 /tmp/a 是否存在:

fs.mkdir('/tmp/a/apple', { recursive: true }, (err) => {
  if (err) throw err;
});

讀取目錄

語法

以下為讀取目錄的語法格式:

fs.readdir(path, callback)

參數

參數使用說明如下:

  • path - 檔路徑。

  • callback - 回調函數,回調函數帶有兩個參數err, files,err 為錯誤資訊,files 為 目錄下的檔數組列表。

實例

接下來我們創建 file.js 檔,代碼如下所示:

var fs = require("fs");

console.log("查看 /tmp 目錄");
fs.readdir("/tmp/",function(err, files){
   if (err) {
       return console.error(err);
   }
   files.forEach( function (file){
       console.log( file );
   });
});

以上代碼執行結果如下:

$ node file.js
查看 /tmp 目錄
input.out
output.out
test
test.txt

刪除目錄

語法

以下為刪除目錄的語法格式:

fs.rmdir(path, callback)

參數

參數使用說明如下:

  • path - 檔路徑。

  • callback - 回調函數,沒有參數。

實例

接下來我們創建 file.js 檔,代碼如下所示:

var fs = require("fs");
// 執行前創建一個空的 /tmp/test 目錄
console.log("準備刪除目錄 /tmp/test");
fs.rmdir("/tmp/test",function(err){
   if (err) {
       return console.error(err);
   }
   console.log("讀取 /tmp 目錄");
   fs.readdir("/tmp/",function(err, files){
      if (err) {
          return console.error(err);
      }
      files.forEach( function (file){
          console.log( file );
      });
   });
});

以上代碼執行結果如下:

$ node file.js
準備刪除目錄 /tmp/test
讀取 /tmp 目錄
……

檔模組方法參考手冊

以下為 Node.js 檔模組相同的方法列表:

序號方法 & 描述
1fs.rename(oldPath, newPath, callback)
非同步 rename().回調函數沒有參數,但可能拋出異常。
2fs.ftruncate(fd, len, callback)
非同步 ftruncate().回調函數沒有參數,但可能拋出異常。
3fs.ftruncateSync(fd, len)
同步 ftruncate()
4fs.truncate(path, len, callback)
非同步 truncate().回調函數沒有參數,但可能拋出異常。
5fs.truncateSync(path, len)
同步 truncate()
6fs.chown(path, uid, gid, callback)
非同步 chown().回調函數沒有參數,但可能拋出異常。
7fs.chownSync(path, uid, gid)
同步 chown()
8fs.fchown(fd, uid, gid, callback)
非同步 fchown().回調函數沒有參數,但可能拋出異常。
9fs.fchownSync(fd, uid, gid)
同步 fchown()
10fs.lchown(path, uid, gid, callback)
非同步 lchown().回調函數沒有參數,但可能拋出異常。
11fs.lchownSync(path, uid, gid)
同步 lchown()
12fs.chmod(path, mode, callback)
非同步 chmod().回調函數沒有參數,但可能拋出異常。
13fs.chmodSync(path, mode)
同步 chmod().
14fs.fchmod(fd, mode, callback)
非同步 fchmod().回調函數沒有參數,但可能拋出異常。
15fs.fchmodSync(fd, mode)
同步 fchmod().
16fs.lchmod(path, mode, callback)
非同步 lchmod().回調函數沒有參數,但可能拋出異常。Only available on Mac OS X.
17fs.lchmodSync(path, mode)
同步 lchmod().
18fs.stat(path, callback)
非同步 stat(). 回調函數有兩個參數 err, stats,stats 是 fs.Stats 對象。
19fs.lstat(path, callback)
非同步 lstat(). 回調函數有兩個參數 err, stats,stats 是 fs.Stats 對象。
20fs.fstat(fd, callback)
非同步 fstat(). 回調函數有兩個參數 err, stats,stats 是 fs.Stats 對象。
21fs.statSync(path)
同步 stat(). 返回 fs.Stats 的實例。
22fs.lstatSync(path)
同步 lstat(). 返回 fs.Stats 的實例。
23fs.fstatSync(fd)
同步 fstat(). 返回 fs.Stats 的實例。
24fs.link(srcpath, dstpath, callback)
非同步 link().回調函數沒有參數,但可能拋出異常。
25fs.linkSync(srcpath, dstpath)
同步 link().
26fs.symlink(srcpath, dstpath[, type], callback)
非同步 symlink().回調函數沒有參數,但可能拋出異常。 type 參數可以設置為 'dir', 'file', 或 'junction' (默認為 'file') 。
27fs.symlinkSync(srcpath, dstpath[, type])
同步 symlink().
28fs.readlink(path, callback)
非同步 readlink(). 回調函數有兩個參數 err, linkString。
29fs.realpath(path[, cache], callback)
非同步 realpath(). 回調函數有兩個參數 err, resolvedPath。
30fs.realpathSync(path[, cache])
同步 realpath()。返回絕對路徑。
31fs.unlink(path, callback)
非同步 unlink().回調函數沒有參數,但可能拋出異常。
32fs.unlinkSync(path)
同步 unlink().
33fs.rmdir(path, callback)
非同步 rmdir().回調函數沒有參數,但可能拋出異常。
34fs.rmdirSync(path)
同步 rmdir().
35fs.mkdir(path[, mode], callback)
S非同步 mkdir(2).回調函數沒有參數,但可能拋出異常。 訪問許可權默認為 0777。
36fs.mkdirSync(path[, mode])
同步 mkdir().
37fs.readdir(path, callback)
非同步 readdir(3). 讀取目錄的內容。
38fs.readdirSync(path)
同步 readdir().返回檔數組列表。
39fs.close(fd, callback)
非同步 close().回調函數沒有參數,但可能拋出異常。
40fs.closeSync(fd)
同步 close().
41fs.open(path, flags[, mode], callback)
非同步打開檔。
42fs.openSync(path, flags[, mode])
同步 version of fs.open().
43fs.utimes(path, atime, mtime, callback)
 
44fs.utimesSync(path, atime, mtime)
修改檔時間戳,檔通過指定的檔路徑。
45fs.futimes(fd, atime, mtime, callback)
 
46fs.futimesSync(fd, atime, mtime)
修改檔時間戳,通過檔描述符指定。
47fs.fsync(fd, callback)
非同步 fsync.回調函數沒有參數,但可能拋出異常。
48fs.fsyncSync(fd)
同步 fsync.
49fs.write(fd, buffer, offset, length[, position], callback)
將緩衝區內容寫入到通過檔描述符指定的檔。
50fs.write(fd, data[, position[, encoding]], callback)
通過檔描述符 fd 寫入檔內容。
51fs.writeSync(fd, buffer, offset, length[, position])
同步版的 fs.write()。
52fs.writeSync(fd, data[, position[, encoding]])
同步版的 fs.write().
53fs.read(fd, buffer, offset, length, position, callback)
通過檔描述符 fd 讀取檔內容。
54fs.readSync(fd, buffer, offset, length, position)
同步版的 fs.read.
55fs.readFile(filename[, options], callback)
非同步讀取檔內容。
56fs.readFileSync(filename[, options])
57fs.writeFile(filename, data[, options], callback)
非同步寫入檔內容。
58fs.writeFileSync(filename, data[, options])
同步版的 fs.writeFile。
59fs.appendFile(filename, data[, options], callback)
非同步追加檔內容。
60fs.appendFileSync(filename, data[, options])
The 同步 version of fs.appendFile.
61fs.watchFile(filename[, options], listener)
查看檔的修改。
62fs.unwatchFile(filename[, listener])
停止查看 filename 的修改。
63fs.watch(filename[, options][, listener])
查看 filename 的修改,filename 可以是檔或目錄。返回 fs.FSWatcher 對象。
64fs.exists(path, callback)
檢測給定的路徑是否存在。
65fs.existsSync(path)
同步版的 fs.exists.
66fs.access(path[, mode], callback)
測試指定路徑用戶許可權。
67fs.accessSync(path[, mode])
同步版的 fs.access。
68fs.createReadStream(path[, options])
返回ReadStream 對象。
69fs.createWriteStream(path[, options])
返回 WriteStream 對象。
70fs.symlink(srcpath, dstpath[, type], callback)
非同步 symlink().回調函數沒有參數,但可能拋出異常。

更多內容,請查看官網檔模組描述:File System