Node.js 檔案系統


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

var fs = require("fs")

非同步與同步

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

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

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

實例

建立input.txt 文件,內容如下:

php中文网官网地址:www.php.cn
文件读取实例

建立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 
同步读取: php中文网官网地址:www.php.cn
文件读取实例

程序执行完毕。
异步读取: php中文网官网地址:www.php.cn
文件读取实例

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


開啟檔案

語法

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

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

參數

參數使用說明如下:

  • path - 檔案的路徑。

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

  • mode - 設定檔案模式(權限),檔案建立預設權限為 0666(可讀,可寫)。

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

flags 參數可以是下列值:

##描述#rr+rsrs+wwxw+wx+aax
Flag
以讀取模式開啟檔案。如果檔案不存在拋出異常。
以讀寫模式開啟檔案。如果檔案不存在拋出異常。
以同步的方式讀取檔案。
以同步的方式讀取和寫入檔案。
以寫入模式開啟文件,如果文件不存在則建立。
類似 'w',但是如果檔案路徑存在,則檔案寫入失敗。
以讀寫模式開啟文件,如果文件不存在則建立。
類似 'w+', 但是如果檔案路徑存在,則檔案讀寫失敗。
以追加模式開啟文件,如果文件不存在則建立。
類似 '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()stats.isDirectory()stats.isBlockDevice()stats.isCharacterDevice()stats.isSymbolicLink()stats.isFIFO()stats.isSocket()

實例

接下來我們建立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(filename, data[, options], callback)

如果檔案存在,則該方法寫入的內容會覆寫舊的檔案內容。

參數

參數使用說明如下:

  • #path - 檔案路徑。

  • 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', '我是通过写入的文件内容!',  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.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 檔案內容為:

php中文网官网地址:www.php.cn

接下來我們建立file.js 文件,程式碼如下所示:

var fs = require("fs");
var buf = new Buffer(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  字节被读取
php中文网官网地址:www.php.cn

#關閉檔案

#語法

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

fs.close(fd, callback)

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

參數

參數使用說明如下:

  • #fd - 透過fs.open() 方法傳回的檔案描述符。

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

實例

input.txt 檔案內容為:

php中文网官网地址:www.php.cn

接下來我們建立file.js 文件,程式碼如下所示:

var fs = require("fs");
var buf = new Buffer(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 
准备打开文件!
文件打开成功!
准备读取文件!
php中文网官网地址:www.php.cn
文件关闭成功

#截取檔案

語法

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

fs.ftruncate(fd, len, callback)

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

參數

參數使用說明如下:

  • #fd - 透過fs.open() 方法傳回的檔案描述符。

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

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

實例

input.txt 檔案內容為:

site:www.php.cn

接下來我們建立file.js 文件,程式碼如下所示:

var fs = require("fs");
var buf = new Buffer(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.php.cn

接下來我們建立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[, mode], callback)

參數

參數使用說明如下:
  • path

    - 檔案路徑。
  • mode

    - 設定目錄權限,預設為 0777。
  • callback

    - 回呼函數,沒有參數。

實例

接下來我們建立file.js 文件,程式碼如下:

var fs = require("fs");

console.log("创建目录 /tmp/test/");
fs.mkdir("/tmp/test/",function(err){
   if (err) {
       return console.error(err);
   }
   console.log("目录创建成功。");
});

以上程式碼執行結果如下:
$ node file.js 
创建目录 /tmp/test/
目录创建成功。

讀取目錄

語法

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

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");

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
input.out
output.out
test
test.txt
读取 /tmp 目录
……


檔案模組方法參考手冊

以下為Node.js 檔案模組相同的方法清單:

##描述
如果是檔案回傳true,否則回傳false。
如果是目錄回傳 true,否則回傳 false。
如果是區塊裝置回傳 true,否則回傳 false。
如果字元裝置傳回 true,否則傳回 false。
如果是軟連結回傳 true,否則回傳 false。
如果是FIFO,回傳true,否則回傳 false。 FIFO是UNIX中的一種特殊類型的命令管道。
如果是 Socket 回傳 true,否則回傳 false。
S非同步mkdir(2).回呼函數沒有參數,但可能拋出例外。 mode defaults to 0777.#同步mkdir().非同步readdir(3). 讀取目錄的內容。 同步 readdir().傳回檔案陣列清單。 異步close().回呼函數沒有參數,但可能會拋出異常。 同步close().fs.open(path, flags[, mode], callback)非同步開啟檔案。
序號方法& 描述
#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 的實例。 ############22#########fs.lstatSync(path)######同步 lstat(). 傳回 fs.Stats 的實例。 ############23#########fs.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[, 型])
同步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().回呼函數沒有參數,但可能會拋出異常。
32#fs.unlinkSync(path)
同步unlink().
33fs.rmdir(path, callback)
非同步rmdir().回呼函數沒有參數,但可能拋出例外。
34fs.rmdirSync(path)
同步rmdir().


35
fs.mkdir(path[, mode], callback)
36
fs.mkdirSync(path[, mode])
37
fs.readdir(path, callback)
38
fs.readdirSync(path)
39
fs.close(fd, callback)
40
fs.closeSync(fd)


# #41
42
###fs.openSync(path, flags[, mode])######同步version of fs.open().# ###########43#########fs.utimes(path, atime, mtime, callback)###### ############ #44#########fs.utimesSync(path, atime, mtime)######修改檔案時間戳,檔案經由指定的檔案路徑。 ############45#########fs.futimes(fd, atime, mtime, callback)###### ########### ##46#########fs.futimesSync(fd, atime, mtime)######修改檔案時間戳,透過檔案描述符指定。
47fs.fsync(fd, callback)
非同步 fsync.回呼函數沒有參數,但可能拋出例外。
48fs.fsyncSync(fd)
#同步fsync.
49 fs.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])<br同步版的fs.readfile.<="" td="">
57#fs.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