- fs模塊下的類與FS常量
- fs模塊下的主要方法
- fs的Promise API與FileHandle類
一、fs模塊下的類
1.1 fs.Dir:表示目錄流的類,由 fs.opendir()
、fs.opendirSync()
或 fsPromises.opendir()
創建。
1.2 fs.Dirent:目錄項的表現形式,通過從fs.Dir中讀取返回。
1.3 fs.FSWatcher:繼承自 <EventEmitter>,調用 fs.watch()
方法返回該對象。每當指定監視的文件被修改時,所有的 fs.FSWatcher
對象都會觸發 'change'
事件。
1.4 fs.ReadStream
:成功調用 fs.createReadStream()
將會返回一個新的 fs.ReadStream
對象。用於讀取流。
1.5 fs.Stats:文件信息對象。從 fs.stat()
、fs.lstat()
和 fs.fstat()
及其同步的方法返回的對象都屬於此類型。
1.6 fs.WriteStream:繼承自 <stream.Writable>,管理文件寫入流。
1.7 FS常量:
1.7.1文件可訪問性,用於fs.access():
F_OK :表明文件對調用進程可見。可以用來判斷文件是否存在,但沒有有rwx權限說明。
R_OK :表明調用進程可以讀取文件。
W_OK :表明調用進程可以寫入文件。
X_OK :表明調用進程可以執行文件。在window系統上無效,表現的像fs.constants.F_OK。
1.7.2文件拷貝常量,用於fs.copyFile()。
COPYFILE_EXCL :如果目標路徑已經存在,則拷貝操作將失敗。
COPYFILE_FICLONE :拷貝操作將嘗試創建寫時拷貝連接。如果底層平台不支持寫時拷貝,則使用備選拷貝機制。
COPYFILE_FICLONE_FORCE :拷貝操作將嘗試創建寫時拷貝連接。如果底層平台不支持寫時拷貝,則拷貝失敗。
1.7.3文件打開的常量,用於fs.open()。
O_RDONLY :表明打開文件用於只讀訪問。 O_WRONLY :表明打開文件用於只寫訪問。 O_RDWR :表明打開文件用於讀寫操作。 O_CREAT :表明如果文件不存在則創建文件。 O_EXCL :表明如果設置了O_CREAT標志且文件已存在,則打開文件應該失敗。 O_NOCTTY :表明如果路徑表示中斷設備,則打開該路徑不應該造成該終端變成進程的控制終端(如果進程還沒有終端)。 O_TRUNC :表明如果文件存在且是常規文件、並且文件成功打開以進行寫入訪問,且長度應截斷為零。 O_APPEND :表明數據將會追加到文件的末尾。 O_DIRECTORY :表明如果路徑不是目錄,則打開應該失敗。 O_NOATIME :表明文件系統的讀取訪問不再導致於文件相關聯的atime信息的更新。僅在Linux系統上有效。 O_NOFOLLOW :表明如果路徑是符號連接,則打開應該失敗。 O_SYNC :表明文件是為同步I/O打開的,寫入操作將會等待文件的完整性。 O_DSYNC :表明文件是為同步I/O打開的,寫入操作將會等待數據的完整性。 O_SYMLINK :表明打開符號連接自身,而不是它指向的資源。 O_DIRECT :表明將嘗試最小化文件I/O的緩沖效果。 O_NONBLOCK :表明在可能的情況下以非阻塞模式打開文件。 UV_FS_O_FILEMAP :當設置后,將會使用內存文件的映射來范文文件。此標志僅在windows系統上有效,其它系統此標志會被忽略。
1.7.4文件類型的常量,用於fs.Stats對象的mode屬性,用於決定文件的類型。
S_IFMT :用於提取文件類型代碼的位掩碼。
S_IFREG :表示常規文件。
S_IFDIR :表示目錄。
S_IFCHR :表示面向字符的設備文件。
S_IFBLK :表示面向塊的設備文件。
S_IFIFO :表示FIFO或管道。
S_IFLNK :表示符號連接。
S_IFSOCK :表示套接字。
1.7.5文件模式常量,用於fs.Stats對象的mode屬性,用於決定文件的訪問權限。
S_IRWXU :表明所有者可讀、可寫、可執行。
S_IRUSE :表明所有者可讀。
S_IWUSR :表明所有者可寫。
S_IXUSR :表明所有者可執行。
S_IRWXG :表明群組可讀、可寫、可執行。
S_IRGRP :表明群組可讀。
S_IWGRP :表明群組可寫。
S_IXGRP : 表明群組可執行。
S_IRWXO :表明群組可讀、可寫、可執行。
S_IROTH :表明其他人可讀。
S_IWOTH :表明其他人可寫。
S_IXOTH :表明其他人可執行。
1.8 FS文件系統標志(flag):
a 可寫、可創建、可追加。(組合標志: a+、ax、as)
——a標志用來追加寫入,如果沒有該文件會創建該文件。
r 可讀。(組合標志:r+、rs 、rs+)
——r標志用來讀取文件,如果沒有該文件會拋出異常。
w 可寫、可創建。(組合標志:w+、wx、wx+)
——w標志用來做寫入操作,如果沒有該文件則創建,如果有該文件則截斷。
——x標志用來表示文件可執行。
——s表示同步阻塞的方式操作文件。
1.9 FS文件操作權限:
文件操作權限分為三個等級:文件所有者權限、同組用戶的權限、非同組用戶的權限。每組權限都用一個數值表示,該數值是由標志轉換加和而來(r對應4;w對應2;x對應1)。
比如在fs.open(path[, flags[, mode]], callback)用來設置用戶權限的是mode參數,該參數默認操作權限是:0o666。0o表示后面的數值為8進制,666按順序分別對應:所有者、同組用戶、非同組用戶。所以這個默認參數所表示的是所有用戶都具備可讀、可寫的權限。
二、fs模塊下的主要方法
2.1 FS.access():測試用戶對Path指定的文件或目錄的權限。
fs.access(path[,mode],callback);//異步:回調函數調用時將傳入可能的錯誤參數,如果權限檢查通過就不會傳入參數。 fs.accessSync(path[,mode]);//同步:如果權限檢查不通過則拋出Error。否則通過的話就返回undefined。
可以使用access檢查文件是否存在(F_OK)、文件是否可讀(R_OK)、文件是否可寫(W_OK)、文件是否可執行(X_OK)。注意windows下“X_OK”無效。
不建議在fs.open()、fs.readFile()、fs.writeFile()【打開文件、讀取文件、寫入文件】之前使用access,相反這些操作建議直接進行,不必要在操作之前進行檢查,以免引發競態。

1 const file = 'package.json'; 2 3 // 檢查當前目錄中是否存在該文件。 4 fs.access(file, fs.constants.F_OK, (err) => { 5 console.log(`${file} ${err ? '不存在' : '存在'}`); 6 }); 7 8 // 檢查文件是否可讀。 9 fs.access(file, fs.constants.R_OK, (err) => { 10 console.log(`${file} ${err ? '不可讀' : '可讀'}`); 11 }); 12 13 // 檢查文件是否可寫。 14 fs.access(file, fs.constants.W_OK, (err) => { 15 console.log(`${file} ${err ? '不可寫' : '可寫'}`); 16 }); 17 18 // 檢查當前目錄中是否存在該文件,以及該文件是否可寫。 19 fs.access(file, fs.constants.F_OK | fs.constants.W_OK, (err) => { 20 if (err) { 21 console.error( 22 `${file} ${err.code === 'ENOENT' ? '不存在' : '只可讀'}`); 23 } else { 24 console.log(`${file} 存在,且它是可寫的`); 25 } 26 }); 27 28 //同步檢查 29 try { 30 fs.accessSync('etc/passwd', fs.constants.R_OK | fs.constants.W_OK); 31 console.log('可以讀寫'); 32 } catch (err) { 33 console.error('無權訪問'); 34 }
2.2 FS.appendFile():將數據追加到文件,如果文件不存在則創建文件。
fs.appendFile(path, data[, options], callback);//異步:options可以配置文件encoding、mode、flag【字符編碼、權限值、文件可操作標志符】,如果寫入一個字符串值只表示字符編碼。 //callbakc:當操作不可操作時會傳入error對象 fs.appendFileSync(path,data[,options]);//同步
path可以指定為已打開的文件的數字型文件描述符,用於追加文件數據。

1 //為指定路徑的文件追加數據 2 fs.appendFile('message.txt', '追加的數據', (err) => { 3 if (err) throw err; 4 console.log('數據已追加到文件'); 5 }); 6 //paht為已打開的文件數字型文件描述符(fd) 7 fs.open('message.txt', 'a', (err, fd) => { 8 if (err) throw err; 9 fs.appendFile(fd, '追加的數據', 'utf8', (err) => { 10 fs.close(fd, (err) => { 11 if (err) throw err; 12 }); 13 if (err) throw err; 14 }); 15 }); 16 17 //同步示例一 18 try { 19 fs.appendFileSync('message.txt', '追加的數據'); 20 console.log('數據已追加到文件'); 21 } catch (err) { 22 /* 處理錯誤 */ 23 } 24 //同步示例二 25 let fd; 26 try { 27 fd = fs.openSync('message.txt', 'a'); 28 fs.appendFileSync(fd, '追加的數據', 'utf8'); 29 } catch (err) { 30 /* 處理錯誤 */ 31 } finally { 32 if (fd !== undefined) 33 fs.closeSync(fd); 34 }
2.3 Fs.chmod():修改文件權限。
fs.chmod(path,mode,callback);//異步:回調函數除了可能的異常對象,沒有其他參數。 fs.chmodSync(path,mode);//同步
關於權限設置的mode參數值詳細可參考第一節中的1.8和1.9的內容。

1 fs.chmod('my_file.txt', 0o775, (err) => { 2 if (err) throw err; 3 console.log('文件 “my_file.txt” 的權限已被更改'); 4 });
2.4Fs.chown():更改文件所有者和群組。
fs.chown(path,uid,gid,callback);//異步:uid-所有者id、gid-群組id fs.chownSync(path,uid,gid);//同步
2.5FS.close():關閉文件,與此對應的是打開文件方法open()。
fs.close(fd,callback);//異步 fs.closeSync(fd);//同步
2.6Fs.constants:返回包文件系統操作常用常量的對象。
詳細內容見第一節1.7。
2.8Fs.copyFile():拷貝文件。
fs.copyFile(src,dest[,flags],callback);//異步 //src:要拷貝的文件 //dest:拷貝操作的目標文件名 //flags:用於拷貝操作修飾符,詳細見第一節1.7.2 //callback:除了可能發生的錯誤err對象沒有其他參數 fs.copyFileSync(src,dest[,flags])

1 //示例一 2 const fs = require('fs'); 3 4 // 默認情況下將創建或覆蓋目標文件。 5 fs.copyFile('源文件.txt', '目標文件.txt', (err) => { 6 if (err) throw err; 7 console.log('源文件已拷貝到目標文件'); 8 }); 9 //示例二 10 const fs = require('fs'); 11 const { COPYFILE_EXCL } = fs.constants; 12 13 // 通過使用 COPYFILE_EXCL,如果目標文件存在,則操作將失敗。 14 fs.copyFile('源文件.txt', '目標文件.txt', COPYFILE_EXCL, callback);
2.9Fs.createReadStream(path[,options]):創建一個讀取文件流對象 <fs.ReadStream>。
path <string> | <Buffer> | <URL> options <string> | <Object> //當optiions為一個字符串時表示字符編碼 //當options為對象時可以包含以下字段: flags--文件標志 encoding--字符編碼 fd--文件描述符(指向僅支持阻塞讀取的字符設備) mode--文件權限 autoClose--默認:true,在error或end事件時關閉文件描述符。當屬性值為false時即使出現錯誤,文件描述符也不會關閉。應用程序需要關閉文件描述符來確保沒有文件描述符泄露。 emitClose--默認:false,流在銷毀后不會觸發‘close’事件。當屬性值為true改變此行為。 start--與end配合讀取文件的范圍。 end--默認:Infinity highWaterMark--默認:64*1024
2.10Fs.createWriteStream(path[, options]):創建一個寫入流對象<fs.WriteStream>。
path <string> | <Buffer> | <URL> options <string> | <Object> //當options為字符串時,該值為字符編碼。 //當options為對象時: flags--文件標志符 encoding--字符編碼 fd--文件描述符 mode--文件權限 autoClose--默認true,當error或finish事件是文件描述符自動關閉。為false時即使出錯文件描述符也不關閉。 emitClose--默認false,流在注銷時不會觸發close事件,反之則出發。 start--允許再文件開頭之后的某個位置寫入數據
2.11Fs.existsSync(path):判斷文件路徑是否存在(同步,對應的異步方法已廢棄)。
//如果路徑存在,則返回 true,否則返回 false。 //示例: if (fs.existsSync('/etc/passwd')) { console.log('文件已存在'); }
2.12Fs.fchmod():修改文件權限。
fs.fchmod(fd,mode,callback);//異步修改文件權限 fs.fchmodSync(fd,mode);//同步修改文件權限 //fd--文件描述符;mode--權限(0o666);callback除了可能出現的error對象沒有其他參數
2.13Fs.fchown():修改文件所有者和群組。
fs.fchown(fd,uid,gid,callback);//異步修改文件所有者和群組 fs.fchownSync(fd,uid,gid);//同步修改文件所有者和群組 //fd--文件描述符;uid--所有者id;gid--群組id;callback除了出現可能的異常傳入error參數以外不需要傳入其他參數
2.14Fs.fdatasync():文件數據同步
fs.fdatasync(fd,callback);//異步 fs.fdatasyncSync(fd);//同步
2.15Fs.fstat():生成文件信息對象fs.Stats
。
fs.fstat(fd[,options],callback);//異步:optiosn只有一個bigint<boolean>字段,默認為false,意思是生成普通fs.stats對象,否則生成BigintStats對象 fs.fstatSync(fd,[options]);//同步
2.16Fs.fsync():文件同步
fs.fsync(fd,callback);//異步實現文件同步 fs.fssyncSync(fd);//同步實現文件同步
2.17Fs.ftruncate():截斷文件
fs.ftruncate(fd[, len], callback);//異步 fs.ftruncateSync(fd[,len]);//同步
如果文件描述符指向的文件大於 len 個字節,則只有前面 len 個字節會保留在文件中。

1 //示例一 2 console.log(fs.readFileSync('temp.txt', 'utf8')); 3 // 打印: Node.js 4 5 // 獲取要截斷的文件的文件描述符。 6 const fd = fs.openSync('temp.txt', 'r+'); 7 8 // 將文件截斷為前 4 個字節。 9 fs.ftruncate(fd, 4, (err) => { 10 assert.ifError(err); 11 console.log(fs.readFileSync('temp.txt', 'utf8')); 12 }); 13 // 打印: Node 14 15 //示例二 16 console.log(fs.readFileSync('temp.txt', 'utf8')); 17 // 打印: Node.js 18 19 // 獲取要截斷的文件的文件描述符。 20 const fd = fs.openSync('temp.txt', 'r+'); 21 22 // 將文件截斷為前 10 個字節,但實際大小為 7 個字節。 23 fs.ftruncate(fd, 10, (err) => { 24 assert.ifError(err); 25 console.log(fs.readFileSync('temp.txt')); 26 }); 27 // 打印: <Buffer 4e 6f 64 65 2e 6a 73 00 00 00> 28 // (UTF8 的值為 'Node.js\0\0\0')
2.18Fs.futimes():更改文件的時間戳
fs.futimes(fd, atime, mtime, callback);//異步 fs.futimesSync(fd, atime, mtime)//同步
2.19Fs.lchmod():修改文件權限。
fs.lchmod(path, mode, callback);//異步:只適應macOS fs.lchmodSync(path, mode)//同步
2.20Fs.lchown():修改文件所有者與群組
fs.lchown(path, uid, gid, callback);//異步 fs.lchownSync(path, uid, gid);//同步
2.21Fs.link():給文件創建新的連接
fs.link(existingPath, newPath, callback);//異步 fs.linkSync(existingPath, newPath);//同步
2.22Fs.lstat():生成文件信息對象。
fs.lstat(path[, options], callback);//異步 fs.lstatSync(path[, options]);//同步
2.23Fs.mkdir():創建目錄。
fs.mkdir(path[, options], callback);//異步 fs.mkdirSync(path[, options]);//同步
options包含兩個字段:recursive<boolean>是否創建父級對象。mode配置文件權限(在windows上無效)

1 // 創建 /tmp/a/apple 目錄,無論是否存在 /tmp 和 /tmp/a 目錄。 2 fs.mkdir('/tmp/a/apple', { recursive: true }, (err) => { 3 if (err) throw err; 4 });
2.24Fs.mkdtemp():創建唯一的臨時目錄。
fs.mkdtemp(prefix[, options], callback);//異步 fs.mkdtempSync(prefix[, options]);//同步
prefix(文件夾名稱不要以x結尾);options<string | object>為一個字符串時直接表示字符編碼,為對象時也只有一個encoding(字符編碼)字段。

1 //示例一 2 fs.mkdtemp(path.join(os.tmpdir(), '目錄-'), (err, folder) => { 3 if (err) throw err; 4 console.log(folder); 5 // 打印: /tmp/目錄-itXde2 或 C:\Users\...\AppData\Local\Temp\目錄-itXde2 6 }); 7 8 //示例二 9 // 新的臨時目錄的父目錄。 10 const tmpDir = os.tmpdir(); 11 12 // 此用法是錯誤的: 13 fs.mkdtemp(tmpDir, (err, folder) => { 14 if (err) throw err; 15 console.log(folder); 16 // 輸出類似 `/tmpabc123`。 17 // 新的臨時目錄會被創建在文件系統根目錄,而不是在 /tmp 目錄中。 18 }); 19 20 // 此用法是正確的: 21 const { sep } = require('path'); 22 fs.mkdtemp(`${tmpDir}${sep}`, (err, folder) => { 23 if (err) throw err; 24 console.log(folder); 25 // 輸出類似 `/tmp/abc123`。 26 // 新的臨時目錄會被創建在 /tmp 目錄中。 27 });
2.25Fs.open():用於打開文件。
fs.open(path[, flags[, mode]], callback);//異步打開文件:回調函數的參數(err,fd) fs.openSync(path[, flags, mode]);//同步打開文件:返回文件描述符fd
如果文件標志flags設置了可寫,當打開文件不存在時會自動創建該文件。
2.26Fs.opendir():用於打開文件夾(目錄)。
fs.opendir(path[, options], callback);//異步打開文件夾,回調函數的參數(err,dir),dir一個文件目錄流對象(fs.dir對象) fs.opendirSync(path[, options]);//同步打開文件夾:返回fs.dir
2.27Fs.read():用於讀取文件。
fs.read(fd, buffer, offset, length, position, callback);//異步讀取。
fs.readSync(fd, buffer, offset, length, position);//同步讀取。返回 bytesRead<number>
的數量。
//fd--文件描述符
//buffer--數據將寫入緩沖區
//offset--buffer寫入的偏移量
//length--指定讀取的字節數
//position--指定開始讀取的位置
//callback--三個參數:err、bytesRead、buffer
2.28Fs.readdir():用於讀取目錄內容。
fs.readdir(path[, options], callback);//異步:回調函數有兩個參數(err,files) fs.readdirSync(path[, options]);//同步:返回文件名數組
讀取的結果為文件名數組,如果options參數中的withFileTypes設置為true則 files 數組將包含 fs.Dirent 對象。
options參數還可以有一個字符編碼字段encoding,除了設置字符編碼值還可以設置為buffer,讀取的文件名數組就是buffer對象。
2.29Fs.readFile():讀取文件。
fs.readFile(path[, options], callback);//異步 fs.readFileSync(path[, options]);//同步:返回文件內容data<string>|<buffer> //path <string> | <Buffer> | <URL> | <integer> 文件名或文件描述符。如果將文件描述符指定為 path,則不會自動關閉它。 //options:{encoding,flag}任何指定的文件描述符都必須支持讀取。 //callback(err,data)--data<string>|<buffer>
2.30Fs.readlink():讀取文件連接。
fs.readlink(path[, options], callback);//異步 fs.readlinkSync(path[, options]);//同步 //path--<string> | <Buffer> | <URL> //options--<string>|<object> :encoding--默認‘utf8’,該值可設置為‘buffer’ //callback(err,linkstring);//當設置encoding為buffer時,文件連接將作為buffer類型,否則為string類型
2.31Fs.realpath():通過解析“.”、“..”計算規范路徑。不同系統環境返回值會有差異。
fs.realpath(path[, options], callback);//異步 fs.realpathSync(path[, options]);//同步 //path--相對路徑 //options--字符編碼<string>|<object>:{encoding} //callback(err,resolvedPath);resolvedPath--絕對路徑
規范路徑名不一定是唯一的。 硬鏈接和綁定裝載可以通過許多路徑名暴露文件系統實體。
此函數的行為類似於 realpath(3),但有一些例外
1.在不區分大小寫的文件系統上不執行大小寫轉換。。
2.符號鏈接的最大數量與平台無關,並且通常高於本地 realpath(3) 實現支持的數量。
callback 有兩個參數 (err, resolvedPath)。 可以使用 process.cwd 來解析相對路徑。
僅支持可轉換為 UTF8 字符串的路徑。

1 function rePath(pathName) { 2 fs.realpath("./fs/"+pathName + ".txt", 'utf8', function(err,resolvedPath){ 3 if(err) throw err; 4 console.log(resolvedPath); 5 }); 6 }
2.32Fs.realpath.native():同realpath基本一致。
fs.realpath.native(path[, options], callback);//異步 fs.realpathSync.native(path[, options]);//同步 //在 Linux 上,當 Node.js 與 musl libc 鏈接時,procfs 文件系統必須掛載在 /proc 上才能使此功能正常工作。 Glibc 沒有這個限制。
2.33Fs.rename():使用新的路徑名稱替換文件原來的路徑名稱,相當於文件剪切+重命名操作。
fs.rename(oldPath, newPath, callback);//異步 fs.renameSync(oldPath, newPath);//同步 //異步地將 oldPath 上的文件重命名為 newPath 提供的路徑名。 如果 newPath 已存在,則覆蓋它。

1 function rename(pathName){ 2 fs.rename("./fs/"+pathName + ".txt","rename.txt",function (err) { 3 if(err) throw err; 4 console.log("重命名完成"); 5 }) 6 }
2.34 Fs.rmdir():用來刪除文件夾。
fs.rmdir(path[, options], callback);//異步 fs.rmdirSync(path[, options]);//同步 //path--文件夾路徑 //options--{emfileWait,maxBusyTries,recursive} //emfileWait--如果發生錯誤,以1毫秒的頻率進行回退,重試操作。該參數默認值1000毫秒,如果在這個設定的時間內重試不成功則拋出錯誤。 //maxBusyTries--以100毫秒為頻率進行回退,重試操作。該操作默認值3,表示重試操作3次。 //recursive--如果設置為true,則執行遞歸刪除目錄,如果path不存在不拋出錯誤,重試該操作,知道超出重試時間或次數。 //--只能刪除空文件夾
2.35Fs.stat():生成文件信息對象fs.stats。
fs.stat(path[, options], callback);//異步 fs.statSync(path[, options]);//同步--返回fs.stats //options<object>{bigint}--bigint返回的 fs.Stats 對象中的數值是否應為 bigint 型。默認值: false。 //callback(err,stats)
2.36Fs.symlink():創建一個鏈接指向文件或目錄。
fs.symlink(target, path[, type], callback);//異步 fs.symlinkSync(target, path[, type]);//同步 //target--目標文件或目錄 //path--鏈接 //type--僅在windows上有用,用來指定文件類型(dir、file、junction),如果找到指定的類型則使用file類型。 //callback(err)
2.37Fs.truncate():截斷文件內容。
fs.truncate(path[, len], callback);//異步callback(err) fs.unlink(path, callback);//同步--返回undefined //len--指定截取文件內容的字節數,從文件內容起始位置到len。(默認參數為0,表示截取文件所有內容) //這個方法盡量不要使用fd(文件描述符)可能導致出錯,盡量使用文件路徑作為path,使用fd的操作可以使用fs.ftruncate()
2.38Fs.unlink():刪除文件
fs.unlink(path, callback);//異步:callback(err) fs.unlinkSync(path);//同步--返回undefined //path--可使用路徑字符串,也可以使用fd文件描述符
2.39Fs.unwatchFile():刪除文件上指定的事件監聽器。
fs.unwatchFile(filename[, listener]); //filename--文件名稱 //listener--監聽器名稱
2.40Fs.utimes():更改指定的文件或文件夾的文件系統時間戳。
fs.utimes(path, atime, mtime, callback);//callback(err) fs.utimesSync(path, atime, mtime) //path--文件、文件夾 //atime--Unix紀元時間的數字值、Date對象、或類似 '123456789.0' 的數值字符串。 //mtime--時間戳
2.41Fs.watch():給文件設置更改時的事件監聽器。
fs.watch(filename[, options][, listener]); //filename--監聽的文件或目錄 //options<string>|object--{persistent,recursive}--persistent指示文件已被監聽,進程是否繼續運行;recursive--指示應該監聽所有子目錄還是監聽當前目錄。 //listener(eventType,filename)--監聽器回調函數 //eventType--事件類型'rename'、'change' //filename--觸發事件的文件名稱
fs.watch不是所有平台都兼容的API,僅在macOS和windows上支持。
- 在 Linux 系統上,使用
inotify(7)
。 - 在 BSD 系統上,使用
kqueue(2)
。 - 在 macOS 系統上,對文件使用
kqueue(2)
,對目錄使用FSEvents
。 - 在 SunOS 系統上(包括 Solaris 和 SmartOS),使用事件端口。
- 在 Windows 系統上,此特性取決於
ReadDirectoryChangesW
。 - 在 Aix 系統上,此特性取決於
AHAFS
必須啟動。
2.42Fs.watchFile():監視 filename
的更改。 每當訪問文件時都會調用 listener
回調。
fs.watchFile(filename[, options], listener);//該方法與fs.watch()非常類是,watch()用於設置文件和目錄的監聽事件;但watchFile只能設置文件的監聽事件 //filename--文件名稱 //options<object>--{persistent,interval}--persistent:指示文件正在被監視,進程是否應該繼續運行;interval指示目錄輪詢頻率 //listener(current,previous) //current--當前最近修改的記錄對象:比如修改的時間curent.mtime //previous--之前最近修改的記錄對象
當 fs.watchFile()
正在監視的文件消失並重新出現時,第二次回調事件(文件重新出現)返回的 previousStat
會與第一次回調事件(文件消失)返回的 previousStat
相同。
這種情況發生在:
- 文件被刪除,然后又恢復。
- 文件被重命名,然后再第二次重命名回其原來的名稱。
2.43Fs.write():將數據寫入到指定位置。(如果不指定位置會覆蓋之前的數據從最開始的位置寫入)
fs.write(fd, string[, position[, encoding]], callback)//異步 fs.writeSync(fd, buffer[, offset[, length[, position]]])//同步--返回一個nummber值,表示寫入的字節數 //fd--文件描述符 //string--數據。如果string不是一個字符串,會被強制轉換成字符串。 //position--指定文件開頭的偏移量(數據應該寫入的位置)。如果position不是number原始類型則從最開始的位置寫入。 //encoding--string【數據】期望的字符串編碼。 //callback(err,written,string) //written--指定字符串要被寫入的字節數
在 Linux 上,當以追加模式打開文件時,寫入無法指定位置。 內核會忽略位置參數,並始終將數據追加到文件的末尾。
在 Windows 上,如果文件描述符連接到控制台(例如 fd == 1
或 stdout
),則無論使用何種編碼,包含非 ASCII 字符的字符串默認情況下都不會被正確地渲染。 通過使用 chcp 65001
命令更改活動的代碼頁,可以將控制台配置為正確地渲染 UTF-8。 詳見 chcp 文檔。
2.44Fs.writeFile():將數據寫入到指定的文件。(如果不指定位置會覆蓋之前的數據從最開始的位置寫入)
fs.writeFile(file, data[, options], callback);//異步 fs.writeFileSync(file, data[, options]);//同步 //當 file 是一個文件名時,異步地將數據寫入到一個文件,如果文件已存在則覆蓋該文件。 data 可以是字符串或 buffer。 //當 file 是一個文件描述符時,行為類似於直接調用 fs.write()(建議使用)。 請參閱以下有關使用文件描述符的說明。 //如果 data 是一個 buffer,則 encoding 選項會被忽略。 //position<string>|<object>--如果該參數為字符串時指示為字符串編碼 //--encoding:字符編碼 //--mode--配置權限 //flag--配置文件標志
在同一個文件上多次使用 fs.writeFile()
且不等待回調是不安全的。 對於這種情況,建議使用 fs.createWriteStream()
。
沒有file時會先創建再寫入。
如果file時一個文件描述符(fd)時,按照以下語法寫入:
fs.write(fd, Buffer.from(data, options.encoding), callback);
2.45Fs.writev():將一個ArrayBufferView數組寫入指定的fd。
fs.writev(fd, buffers[, position], callback);//異步 fs.writevSync(fd, buffers[, position]);//同步--返回寫入的字節數 //fd--文件描述符 //buffers--<ArrayBufferView[]> //position--指定文件開頭的偏移量 //callback(err,bytesWritten,buffers) //bytesWritten--寫入的字節數
三、fs的Promise API與FileHandle類
在了解這部分內容之前建議先了解Promise,我之前有一篇詳細的Promise的解析博客可以提供參考:ES6入門八:Promise異步編程與模擬實現源碼。
在官方文檔中明確表示為一組備用的API,也就是這部分API在將來可能發生變化,慎用。(有空閑的時間再來補充)