IO.js File System

2018-11-28 22:34 更新

穩(wěn)定度: 2 - 穩(wěn)定

文件I/O是由標(biāo)準(zhǔn)POSIX函數(shù)的簡(jiǎn)單包裝提供的。通過(guò)require('fs')來(lái)使用這個(gè)模塊。所有的方法都有異步和同步兩種形式。

異步形式的方法通常在最后一個(gè)參數(shù)上接受一個(gè)回調(diào)函數(shù)?;卣{(diào)函數(shù)的參數(shù)則取決于不同的方法,但是第一個(gè)參數(shù)總是為異常所保留。如果操作正常結(jié)束,那么第一個(gè)參數(shù)會(huì)是nullundefined。

當(dāng)同步形式的方法產(chǎn)生異常時(shí),會(huì)立刻拋出。你可以使用try/catch捕獲,或讓它們冒泡。

下面是一個(gè)異步方法的例子:

var fs = require('fs');

fs.unlink('/tmp/hello', function (err) {
  if (err) throw err;
  console.log('successfully deleted /tmp/hello');
});

下面是一個(gè)同步方法的例子:

var fs = require('fs');

fs.unlinkSync('/tmp/hello');
console.log('successfully deleted /tmp/hello');

因?yàn)楫惒椒椒ú荒軌虮WC執(zhí)行順序,所以下面的例子很容易出錯(cuò):

fs.rename('/tmp/hello', '/tmp/world', function (err) {
  if (err) throw err;
  console.log('renamed complete');
});
fs.stat('/tmp/world', function (err, stats) {
  if (err) throw err;
  console.log('stats: ' + JSON.stringify(stats));
});

它需要在fs.rename后執(zhí)行fs.stat。正確的執(zhí)行方法應(yīng)如下:

fs.rename('/tmp/hello', '/tmp/world', function (err) {
  if (err) throw err;
  fs.stat('/tmp/world', function (err, stats) {
    if (err) throw err;
    console.log('stats: ' + JSON.stringify(stats));
  });
});

在繁忙的進(jìn)程中,十分推薦使用異步版本的方法。同步版本的方法會(huì)阻塞進(jìn)程,直到它們完成,也就是說(shuō)它們會(huì)暫停所有連接。

文件的相對(duì)路徑也可以被使用,記住路徑是相對(duì)于process.cwd()的。

大多數(shù)的fs函數(shù)允許你省略回調(diào)函數(shù)。如果你省略了,將會(huì)由一個(gè)默認(rèn)的回調(diào)函數(shù)來(lái)重拋出(rethrows)錯(cuò)誤。要獲得原始調(diào)用地點(diǎn)的堆棧追蹤信息,請(qǐng)?jiān)O(shè)置NODE_DEBUG環(huán)境變量:

$ cat script.js
function bad() {
  require('fs').readFile('/');
}
bad();

$ env NODE_DEBUG=fs iojs script.js
fs.js:66
        throw err;
              ^
Error: EISDIR, read
    at rethrow (fs.js:61:21)
    at maybeCallback (fs.js:79:42)
    at Object.fs.readFile (fs.js:153:18)
    at bad (/path/to/script.js:2:17)
    at Object.<anonymous> (/path/to/script.js:5:1)
    <etc.>

fs.rename(oldPath, newPath, callback)

異步版本的rename(2)?;卣{(diào)函數(shù)只有一個(gè)可能的異常參數(shù)。

fs.renameSync(oldPath, newPath)

同步版本的rename(2)。返回undefined。

fs.ftruncate(fd, len, callback)

異步版本的ftruncate(2)。回調(diào)函數(shù)只有一個(gè)可能的異常參數(shù)。

fs.ftruncateSync(fd, len)

同步版本的ftruncate(2)。返回undefined

fs.truncate(path, len, callback)

異步版本的truncate(2)。回調(diào)函數(shù)只有一個(gè)可能的異常參數(shù)。第一個(gè)參數(shù)也可以接受一個(gè)文件描述符,這樣的話,fs.ftruncate()會(huì)被調(diào)用。

fs.truncateSync(path, len)

同步版本的truncate(2)。返回undefined。

fs.chown(path, uid, gid, callback)

異步版本的chown(2)?;卣{(diào)函數(shù)只有一個(gè)可能的異常參數(shù)。

fs.chownSync(path, uid, gid)

同步版本的chown(2)。返回undefined

fs.fchown(fd, uid, gid, callback)

異步版本的fchown(2)。回調(diào)函數(shù)只有一個(gè)可能的異常參數(shù)。

fs.fchownSync(fd, uid, gid)

同步版本的fchown(2)。返回undefined

fs.lchown(path, uid, gid, callback)

異步版本的lchown(2)。回調(diào)函數(shù)只有一個(gè)可能的異常參數(shù)。

fs.lchownSync(path, uid, gid)

同步版本的lchown(2)。返回undefined。

fs.chmod(path, mode, callback)

異步版本的chmod(2)?;卣{(diào)函數(shù)只有一個(gè)可能的異常參數(shù)。

fs.chmodSync(path, mode)

同步版本的chmod(2)。返回undefined

fs.fchmod(fd, mode, callback)

異步版本的fchmod(2)?;卣{(diào)函數(shù)只有一個(gè)可能的異常參數(shù)。

fs.fchmodSync(fd, mode)

同步版本的fchmod(2)。返回undefined。

fs.lchmod(path, mode, callback)

異步版本的lchmod(2)?;卣{(diào)函數(shù)只有一個(gè)可能的異常參數(shù)。

僅在Mac OS X中可用。

fs.lchmodSync(path, mode)

同步版本的lchmod(2)。返回undefined。

fs.stat(path, callback)

異步版本的stat(2)。回調(diào)函數(shù)有兩個(gè)參數(shù)(err, stats),stats是一個(gè)fs.Stats對(duì)象。更多信息請(qǐng)參閱fs.Stats章節(jié)。

fs.lstat(path, callback)

異步版本的lstat(2)?;卣{(diào)函數(shù)有兩個(gè)參數(shù)(err, stats),stats是一個(gè)fs.Stats對(duì)象。lstat()stat()是相同的,除了path是一個(gè)符號(hào)鏈接,連接自己本身就是stat-ed,而不是引用一個(gè)文件。

fs.fstat(fd, callback)

異步版本的fstat(2)?;卣{(diào)函數(shù)有兩個(gè)參數(shù)(err, stats),stats是一個(gè)fs.Stats對(duì)象。fstat()stat()是相同的,除了將要被stat-ed的文件是通過(guò)文件描述符fd來(lái)指定的。

fs.statSync(path)

同步版本的stat(2)。返回一個(gè)fs.Stats實(shí)例。

fs.lstatSync(path)

同步版本的lstat(2)。返回一個(gè)fs.Stats實(shí)例。

fs.fstatSync(fd)

同步版本的fstat(2)。返回一個(gè)fs.Stats實(shí)例。

fs.link(srcpath, dstpath, callback)

異步版本的link(2)?;卣{(diào)函數(shù)只有一個(gè)可能的異常參數(shù)。

fs.linkSync(srcpath, dstpath)

同步版本的link(2)。返回undefined。

fs.symlink(destination, path[, type], callback)

異步版本的symlink(2)?;卣{(diào)函數(shù)只有一個(gè)可能的異常參數(shù)。type參數(shù)可以被設(shè)置為'dir','file''junction'(默認(rèn)為'file'),并且僅在Windows平臺(tái)下可用(其他平臺(tái)下會(huì)被忽略)。注意Windows junction點(diǎn) 要求目標(biāo)路徑必須是絕對(duì)的。當(dāng)使用'junction'時(shí),destination參數(shù)會(huì)被自動(dòng)轉(zhuǎn)換為絕對(duì)路徑。

fs.symlinkSync(destination, path[, type])

同步版本的symlink(2)。返回undefined。

fs.readlink(path, callback)

異步版本的link(2)?;卣{(diào)函數(shù)有兩個(gè)參數(shù)(err, linkString)。

fs.readlinkSync(path)

異步版本的readlink(2),返回一個(gè)符號(hào)鏈接字符串值。

fs.realpath(path[, cache], callback)

異步版本的realpath(2)?;卣{(diào)函數(shù)有兩個(gè)參數(shù)(err, resolvedPath)??赡軙?huì)使用process.cwd來(lái)解析相對(duì)路徑。cache是一個(gè)包含了路徑映射的對(duì)象,被用來(lái) 強(qiáng)制進(jìn)行指定的路徑解析 或 避免對(duì)真實(shí)路徑調(diào)用額外的fs.stat。

例子:

var cache = {'/etc':'/private/etc'};
fs.realpath('/etc/passwd', cache, function (err, resolvedPath) {
  if (err) throw err;
  console.log(resolvedPath);
});

fs.realpathSync(path[, cache])

同步版本的realpath(2),返回一個(gè)解析出的路徑。

fs.unlink(path, callback)

異步版本的unlink(2)。回調(diào)函數(shù)只有一個(gè)可能的異常參數(shù)。

fs.unlinkSync(path)

同步版本的unlink(2)。返回undefined

fs.rmdir(path, callback)

異步版本的rmdir(2)?;卣{(diào)函數(shù)只有一個(gè)可能的異常參數(shù)。

fs.rmdirSync(path)

同步版本的rmdir(2)。返回undefined。

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

異步版本的mkdir(2)?;卣{(diào)函數(shù)只有一個(gè)可能的異常參數(shù)。mode默認(rèn)為0o777

fs.mkdirSync(path[, mode])

同步版本的mkdir(2)。返回undefined。

fs.readdir(path, callback)

異步版本的readdir(3)。讀取目錄內(nèi)容。回調(diào)函數(shù)有兩個(gè)參數(shù)(err, files),files是一個(gè)目錄中的文件名數(shù)組(不包括'.''..')。

fs.readdirSync(path)

同步版本的readdir(3)。返回一個(gè)文件名數(shù)組(不包括'.''..')。

fs.close(fd, callback)

異步版本的close(2)?;卣{(diào)函數(shù)只有一個(gè)可能的異常參數(shù)。

fs.closeSync(fd)

同步版本的close(2)。返回undefined。

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

異步版本的文件打開(kāi)。參閱open(2)。flag可以是:

  • 'r' - 以只讀的方式打開(kāi)文件。如果文件不存在則拋出異常。

  • 'r+' - 以讀寫(xiě)的方式打開(kāi)文件。如果文件不存在則拋出異常。

  • 'rs' - 同步地以只讀的方式打開(kāi)文件。繞過(guò)操作系統(tǒng)的本地文件系統(tǒng)緩存。

該功能主要用于打開(kāi)NFS掛載的文件,因?yàn)樗试S你跳過(guò)潛在的過(guò)時(shí)的本地緩存。它對(duì)I/O性能有非常大的影響,所以除非需要它,否則不應(yīng)使用這個(gè)flag

注意這個(gè)flag不會(huì)將fs.open()變?yōu)橐粋€(gè)同步調(diào)用。因?yàn)槿绻阆胍秸{(diào)用,你應(yīng)使用fs.openSync()。

  • 'rs+' - 以讀寫(xiě)的方式打開(kāi)文件,告訴操作系統(tǒng)同步地打開(kāi)它。注意事項(xiàng)請(qǐng)參閱'rs'

  • 'w' - 以只寫(xiě)的方式打開(kāi)文件。如果文件不存在,將會(huì)創(chuàng)建它。如果已存在,將會(huì)覆蓋它。

  • 'wx' - 類(lèi)似于'w',但是路徑不存在時(shí)會(huì)失敗。

  • 'w+' - 以讀寫(xiě)的方式打開(kāi)文件。如果文件不存在,將會(huì)創(chuàng)建它。如果已存在,將會(huì)覆蓋它。

  • 'wx+' - 類(lèi)似于'w+',但是路徑不存在時(shí)會(huì)失敗。

  • 'a' - 以附加的形式打開(kāi)文件。如果文件不存在,將會(huì)創(chuàng)建它。

  • 'ax' - 類(lèi)似于'a',但是路徑不存在時(shí)會(huì)失敗。

  • 'a+' - 以讀取和附加的形式打開(kāi)文件。如果文件不存在,將會(huì)創(chuàng)建它。

  • 'ax+' - 類(lèi)似于'a+',但是路徑不存在時(shí)會(huì)失敗。

參數(shù)mode用于設(shè)置文件模式(權(quán)限和sticky bits),但是前提是文件已被創(chuàng)建。它默認(rèn)為0666,有可讀和可寫(xiě)權(quán)限。

回調(diào)函數(shù)有兩個(gè)參數(shù)(err, fd)。

排除標(biāo)識(shí)'x'open(2)中的O_EXCL標(biāo)識(shí))保證了目錄是被新創(chuàng)建的。在POSIX系統(tǒng)上,即使路徑指向了一個(gè)不存在的符號(hào)鏈接,也會(huì)被認(rèn)定為文件存在。排除標(biāo)識(shí)不能保證在網(wǎng)絡(luò)文件系統(tǒng)中有效。

在Linux下,無(wú)法對(duì)以追加形式打開(kāi)的文件,在指定位置寫(xiě)入數(shù)據(jù)。內(nèi)核忽略了位置參數(shù)并且總是將數(shù)據(jù)追加到文件的末尾。

fs.openSync(path, flags[, mode])

同步版本的fs.open(),返回代表文件描述符的一個(gè)整數(shù)。

fs.utimes(path, atime, mtime, callback)

更改path所指向的文件的時(shí)間戳。

fs.utimesSync(path, atime, mtime)

同步版本的fs.utimes()。返回undefined

fs.futimes(fd, atime, mtime, callback)

更改文件描述符fd所指向的文件的時(shí)間戳。

fs.futimesSync(fd, atime, mtime)

同步版本的fs.futimes()。返回undefined。

fs.fsync(fd, callback)

異步版本的fsync(2)?;卣{(diào)函數(shù)只有一個(gè)可能的異常參數(shù)。

fs.fsyncSync(fd)

同步版本的fsync(2)。返回undefined。

fs.write(fd, buffer, offset, length[, position], callback)

向文件描述符fd指向的文件寫(xiě)入buffer。

offsetlength決定了buffer的哪一部分被寫(xiě)入文件。

position指定了文件中,數(shù)據(jù)被寫(xiě)入的開(kāi)始位置的偏移量。如果typeof position !== 'number',那么數(shù)據(jù)將會(huì)在當(dāng)前位置被寫(xiě)入。參閱pwrite(2)

回調(diào)函數(shù)有三個(gè)參數(shù)(err, written, buffer)。written指出了buffer中有多少字節(jié)被寫(xiě)入。

注意,不等待回調(diào)函數(shù)而多次執(zhí)行fs.write是不安全的。這種情況下推薦使用fs.createWriteStream。

在Linux下,無(wú)法對(duì)以追加形式打開(kāi)的文件,在指定位置寫(xiě)入數(shù)據(jù)。內(nèi)核忽略了位置參數(shù)并且總是將數(shù)據(jù)追加到文件的末尾。

fs.write(fd, data[, position[, encoding]], callback)

向文件描述符fd指向的文件寫(xiě)入data。如果data不是一個(gè)Buffer實(shí)例,那么其值將被強(qiáng)制轉(zhuǎn)化為一個(gè)字符串。

position指定了文件中,數(shù)據(jù)被寫(xiě)入的開(kāi)始位置的偏移量。如果typeof position !== 'number',那么數(shù)據(jù)將會(huì)在當(dāng)前位置被寫(xiě)入。參閱pwrite(2)。

encoding是期望的字符串編碼。

回調(diào)函數(shù)有三個(gè)參數(shù)(err, written, buffer)。written指出了buffer中有多少字節(jié)被寫(xiě)入。注意,寫(xiě)入的字節(jié)與字符串字符是不同的。參閱Buffer.byteLength。

與寫(xiě)入buffer不同,整個(gè)字符串都必須被寫(xiě)入。不能指定子字符串。因?yàn)樽止?jié)的偏移量可能與字符串的偏移量不相同。

注意,不等待回調(diào)函數(shù)而多次執(zhí)行fs.write是不安全的。這種情況下推薦使用fs.createWriteStream。

在Linux下,無(wú)法對(duì)以追加形式打開(kāi)的文件,在指定位置寫(xiě)入數(shù)據(jù)。內(nèi)核忽略了位置參數(shù)并且總是將數(shù)據(jù)追加到文件的末尾。

fs.writeSync(fd, buffer, offset, length[, position])

fs.writeSync(fd, data[, position[, encoding]])

同步版本的fs.write()。返回被寫(xiě)入的字節(jié)數(shù)。

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

從文件描述符fd指向的文件讀取數(shù)據(jù)。

buffer是數(shù)據(jù)將要被寫(xiě)入的緩沖區(qū)。

offset是開(kāi)始向buffer寫(xiě)入數(shù)據(jù)的緩沖區(qū)偏移量。

length是一個(gè)指定了讀取字節(jié)數(shù)的整數(shù)。

position是一個(gè)指定了從文件的何處開(kāi)始讀取數(shù)據(jù)的整數(shù)。如果positionnull,數(shù)據(jù)將會(huì)從當(dāng)前位置開(kāi)始讀取。

回調(diào)函數(shù)有三個(gè)參數(shù)(err, bytesRead, buffer)。

fs.readSync(fd, buffer, offset, length, position)

同步版本的fs.read。返回讀取字節(jié)的個(gè)數(shù)。

fs.readFile(filename[, options], callback)

  • filename String
  • options Object | String

  • encoding String | Null 默認(rèn)為null
  • flag String 默認(rèn)為'r'

  • callback Function

異步得讀取文件的所有內(nèi)容。例子:

fs.readFile('/etc/passwd', function (err, data) {
  if (err) throw err;
  console.log(data);
});

回調(diào)函數(shù)有兩個(gè)參數(shù)(err, data),data是文件的內(nèi)容。

如果沒(méi)有指定編碼,那么將會(huì)返回源buffer。

如果options是一個(gè)字符串,那么它將指定編碼,例子:

fs.readFile('/etc/passwd', 'utf8', callback);

fs.readFileSync(filename[, options])

同步版本的fs.readFile。返回文件的內(nèi)容。

如果指定了編碼那么將會(huì)返回字符串。否則返回buffer。

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

  • filename String
  • data String | Buffer
  • options Object | String

  • encoding String | Null 默認(rèn)為'utf8'
  • mode Number 默認(rèn)為0o666
  • flag String 默認(rèn)為'w'

  • callback Function

異步地向文件寫(xiě)入數(shù)據(jù),如果文件已經(jīng)存在,那么會(huì)覆蓋它。data可以是一個(gè)字符串或一個(gè)buffer。

如果數(shù)據(jù)時(shí)一個(gè)buffer那么編碼會(huì)被忽略。編碼默認(rèn)為'utf8'

例子:

fs.writeFile('message.txt', 'Hello io.js', function (err) {
  if (err) throw err;
  console.log('It\'s saved!');
});

如果options是一個(gè)字符串,那么它將指定編碼,例子:

fs.writeFile('message.txt', 'Hello io.js', 'utf8', callback);

fs.writeFileSync(filename, data[, options])

同步版本的fs.writeFile。返回undefined

fs.appendFile(filename, data[, options], callback)

  • filename String
  • data String | Buffer
  • options Object | String

  • encoding String | Null 默認(rèn)為'utf8'
  • mode Number 默認(rèn)為0o666
  • flag String 默認(rèn)為'a'

  • callback Function

異步地向文件追加數(shù)據(jù),如果文件不存在將會(huì)創(chuàng)建它。data可以是一個(gè)字符串或一個(gè)buffer。

例子:

fs.appendFile('message.txt', 'data to append', function (err) {
  if (err) throw err;
  console.log('The "data to append" was appended to file!');
});

如果options是一個(gè)字符串,那么它將指定編碼,例子:

fs.appendFile('message.txt', 'data to append', 'utf8', callback);

fs.appendFileSync(filename, data[, options])

同步版本的fs.appendFile。返回undefined。

fs.watchFile(filename[, options], listener)

監(jiān)視文件變化。回調(diào)函數(shù)listener會(huì)在文件每一次被訪問(wèn)時(shí)調(diào)用。

第二參數(shù)是可選的。如果options被提供,那么它必須是一個(gè)含有兩個(gè)成員persistentinterval的對(duì)象。persistent表明了進(jìn)程是否在文件被監(jiān)視時(shí)繼續(xù)執(zhí)行。interval表明了文件被輪詢(xún)的間隔(毫秒)。默認(rèn)是{ persistent: true, interval: 5007 }。

listener有兩個(gè)參數(shù),當(dāng)前狀態(tài)對(duì)象和先前狀態(tài)對(duì)象:

fs.watchFile('message.text', function (curr, prev) {
  console.log('the current mtime is: ' + curr.mtime);
  console.log('the previous mtime was: ' + prev.mtime);
});

這兩個(gè)狀態(tài)對(duì)象都是fs.Stat實(shí)例。

如果你想要在文件被修改時(shí)被通知,而不僅僅是在被訪問(wèn)時(shí),你需要比較curr.mtimeprev.mtime。

注意:fs.watchfs.watchFilefs.unwatchFile更高效。當(dāng)可能時(shí),請(qǐng)使用fs.watch替代它們。

fs.unwatchFile(filename[, listener])

停止監(jiān)視filename的變化。如果指定了listener,那么僅僅會(huì)移除指定的listener。否則所有的監(jiān)聽(tīng)器都會(huì)被移除,并且停止繼續(xù)監(jiān)視文件。

對(duì)一個(gè)沒(méi)有被監(jiān)視的文件調(diào)用fs.unwatchFile()將不會(huì)發(fā)生任何事,而不是報(bào)錯(cuò)。

注意:fs.watchfs.watchFilefs.unwatchFile更高效。當(dāng)可能時(shí),請(qǐng)使用fs.watch替代它們。

fs.watch(filename[, options][, listener])

監(jiān)視filename的變化,filename指向的可以是文件也可以是目錄。返回一個(gè)fs.FSWatcher對(duì)象。

第二個(gè)參數(shù)是可選的。options必須是一個(gè)對(duì)象。支持的布爾值屬性是persistentrecursivepersistent表明了進(jìn)程是否在文件被監(jiān)視時(shí)繼續(xù)執(zhí)行。recursive表明了是否子目錄也需要被監(jiān)視,或僅僅監(jiān)視當(dāng)前目錄。這只在支持的平臺(tái)(參閱下方警告)下傳遞一個(gè)目錄時(shí)有效。

默認(rèn)是{ persistent: true, recursive: false }。

listener回調(diào)函數(shù)有兩個(gè)參數(shù)(event, filename)。event'rename''change'filename是觸發(fā)事件的文件名。

警告

fs.watch API 不是在所有平臺(tái)下都表現(xiàn)一致的,并且在一些情況下是不可用的。

recursive選項(xiàng)目前只支持OS X。只有FSEvents支持這種類(lèi)型的文件監(jiān)控,所有其他平臺(tái)并不會(huì)很快都被支持。

可用性

這個(gè)特性依賴(lài)于底層操作系統(tǒng)提供的文件變化提示。

  • 在Linux系統(tǒng)下,它使用inotify。
  • 在BSD系統(tǒng)下,它使用kqueue。
  • 在OS X下,對(duì)于文件它使用kqueue,對(duì)于目錄它使用FSEvents
  • 在SunOS系統(tǒng)(包括SolarisSmartOS)下,它使用事件端口(event ports)。
  • 在Windows系統(tǒng)下,這個(gè)特性依賴(lài)于ReadDirectoryChangesW。

如果由于一些原因,底層功能不可用,那么fs.watch的功能也將不可用。例如,在網(wǎng)絡(luò)文件系統(tǒng)(NFS,SMB等)中監(jiān)視文件或目錄變化,往往結(jié)果不可靠或完全不可用。

你仍可以使用fs.watchFile,它使用了狀態(tài)輪詢(xún)。但是性能更差且可靠性更低。

Filename 參數(shù)

回調(diào)函數(shù)中提供的filename參數(shù)不是在所有平臺(tái)上都支持的(目前只支持Linux和Windows)。即使是在支持的平臺(tái)上,filename也不是總會(huì)被提供。因此,不要假設(shè)filename參數(shù)總會(huì)在回調(diào)函數(shù)中被提供,需要有一些檢測(cè)它是否為null的邏輯。

fs.watch('somedir', function (event, filename) {
  console.log('event is: ' + event);
  if (filename) {
    console.log('filename provided: ' + filename);
  } else {
    console.log('filename not provided');
  }
});

fs.exists(path, callback)

fs.exists()已被棄用。請(qǐng)使用fs.statfs.access替代。

檢查文件系統(tǒng)來(lái)測(cè)試提供的路徑是否存在。然后在回調(diào)函數(shù)的參數(shù)中提供結(jié)果truefalse

fs.exists('/etc/passwd', function (exists) {
  util.debug(exists ? "it's there" : "no passwd!");
});

fs.exists()是一個(gè)不符合潮流的函數(shù),并且僅因一些歷史原因所以仍然錯(cuò)在。在你的代碼中,不應(yīng)有任何原因要繼續(xù)使用它。

特別的,在打開(kāi)文件前檢查文件是否存在 是一種反模式。因?yàn)楦?jìng)態(tài)條件所以讓你的代碼十分脆弱:其他進(jìn)程可能fs.exists()fs.open()之間刪除文件。所以?xún)H僅就去打開(kāi)一個(gè)文件,并且當(dāng)它不存在時(shí)處理錯(cuò)誤。

fs.existsSync(path)

同步版本的fs.exists。當(dāng)文件存在,返回true,否則返回false。

fs.existsSync()已被棄用。請(qǐng)使用fs.statSyncfs.accessSync替代。

fs.access(path[, mode], callback)

對(duì)于指定的路徑,檢測(cè)用戶(hù)的權(quán)限。mode是一個(gè)可選的整數(shù),指定了要被執(zhí)行的可訪問(wèn)性檢查。以下是mode的一些可用的常量??梢酝ㄟ^(guò)“或”運(yùn)算符(|)連接兩個(gè)或以上的值。

  • fs.F_OK - 文件對(duì)于當(dāng)前進(jìn)程可見(jiàn)。這對(duì)于檢查文件是否存在很有用,但是不提供任何rwx權(quán)限信息。這是默認(rèn)值。
  • fs.R_OK - 文件對(duì)于當(dāng)前進(jìn)程可讀。
  • fs.W_OK - 文件對(duì)于當(dāng)前進(jìn)程可寫(xiě)。
  • fs.X_OK - 文件對(duì)于當(dāng)前進(jìn)程可執(zhí)行。這在Windows上無(wú)效(將會(huì)表現(xiàn)得像fs.F_OK一樣)。

最后一個(gè)參數(shù)callback,是一個(gè)包含了潛在錯(cuò)誤參數(shù)的回調(diào)函數(shù)。如果任何一個(gè)可訪問(wèn)檢查失敗了,錯(cuò)誤參數(shù)就會(huì)被提供。以下是一個(gè)在當(dāng)前進(jìn)程中檢查/etc/passwd可讀性和可寫(xiě)性的例子。

fs.access('/etc/passwd', fs.R_OK | fs.W_OK, function(err) {
  util.debug(err ? 'no access!' : 'can read/write');
});

fs.accessSync(path[, mode])

同步版本的fs.access。如果任何一個(gè)可訪問(wèn)性檢查失敗了,它會(huì)拋出異常。否則什么都不做。

Class: fs.Stats

fs.stat(),fs.lstat()fs.lstat()和它們的同步版本函數(shù)所返回的對(duì)象。

  • stats.isFile()
  • stats.isDirectory()
  • stats.isBlockDevice()
  • stats.isCharacterDevice()
  • stats.isSymbolicLink() (僅在調(diào)用fs.lstat()時(shí)有效)
  • stats.isFIFO()
  • stats.isSocket()

對(duì)于一個(gè)普通的文件,util.inspect(stats)可能會(huì)返回:

{ dev: 2114,
  ino: 48064969,
  mode: 33188,
  nlink: 1,
  uid: 85,
  gid: 100,
  rdev: 0,
  size: 527,
  blksize: 4096,
  blocks: 8,
  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 }

請(qǐng)注意,atime,mtimebirthtimectime都是Date對(duì)象實(shí)例,并且你可以通過(guò)合適的方法來(lái)比較它們的值。普遍的使用方式是,調(diào)用getTime()來(lái)獲取unix時(shí)間戳并且這個(gè)整數(shù)可以被用來(lái)進(jìn)行任何比較。但是還有一些可以展示模糊信息的方法。更多的詳細(xì)信息請(qǐng)參閱MDN JavaScript Reference頁(yè)。

Stat 時(shí)間值

stat對(duì)象中的各個(gè)時(shí)間有如下語(yǔ)義:

  • atime "訪問(wèn)時(shí)間" - 文件數(shù)據(jù)最后一次被訪問(wèn)時(shí)的時(shí)間。由mknod(2)utimes(2)read(2)系統(tǒng)調(diào)用改變。
  • mtime "修改時(shí)間" - 文件數(shù)據(jù)最后一次被修改的時(shí)間。由mknod(2),utimes(2)write(2)系統(tǒng)調(diào)用改變。
  • ctime "改變時(shí)間" - 文件狀態(tài)最后一次被改變(索引節(jié)點(diǎn)改變)的時(shí)間。由chmod(2),chown(2),link(2),mknod(2),rename(2),unlink(2)utimes(2),read(2)write(2)系統(tǒng)調(diào)用改變。
  • birthtime "創(chuàng)建時(shí)間" - 文件的創(chuàng)建時(shí)間。在文件被創(chuàng)建時(shí)設(shè)置。在創(chuàng)建時(shí)間不可用的的文件系統(tǒng)上,這個(gè)值可能會(huì)被ctime或是1970-01-01T00:00Z(unix時(shí)間戳0)填充。在Darwin或其他FreeBSD系統(tǒng)變體上,如果使用utimes(2)系統(tǒng)調(diào)用設(shè)置atime為一個(gè)比當(dāng)前birthtime更早的時(shí)間,birthtime也會(huì)被這樣填充。

io.js v1.0 和 Node v0.12 前,Windows系統(tǒng)中ctime持有了birthtime值。但是在 v0.12 里,ctime不再是“創(chuàng)建時(shí)間”。在Unix系統(tǒng)中,它從來(lái)都不是。

fs.createReadStream(path[, options])

返回一個(gè)新的可讀流對(duì)象(參閱Readable Stream)。

options是一個(gè)有以下默認(rèn)值的對(duì)象或字符串:

{ flags: 'r',
  encoding: null,
  fd: null,
  mode: 0o666,
  autoClose: true
}

options可以包含startend值來(lái)讀取指定范圍的文件數(shù)據(jù)。startend這兩個(gè)位置本身,也都是被包括的,并且start0開(kāi)始。編碼可以是'utf8','ascii''base64'。

如果指定了fd,可讀流將會(huì)忽略path參數(shù)并且將會(huì)使用指定的文件描述符。這意味open事件不再會(huì)觸發(fā)。

如果autoClosefalse,那么文件描述符將不會(huì)被關(guān)閉,甚至是有錯(cuò)誤發(fā)生時(shí)。關(guān)閉它將是你的責(zé)任,并且要確保沒(méi)有文件描述符泄漏。如果autoClosetrue(默認(rèn)),那么在發(fā)生錯(cuò)誤時(shí),或到達(dá)文件描述末端時(shí),它會(huì)被自動(dòng)關(guān)閉。

從一個(gè)100字節(jié)的文件中讀取最后10字節(jié)數(shù)據(jù)的例子:

fs.createReadStream('sample.txt', {start: 90, end: 99});

如果options是一個(gè)字符串,那么它表示指定的編碼。

Class: fs.ReadStream

ReadStream是一個(gè)可讀流。

Event: 'open'

  • fd Integer 被可讀流使用的文件描述符

當(dāng)可讀流文件被打開(kāi)時(shí)觸發(fā)。

fs.createWriteStream(path[, options])

返回一個(gè)新的可寫(xiě)流對(duì)象(參閱Writable Stream)。

options是一個(gè)有以下默認(rèn)值的對(duì)象或字符串:

{ flags: 'w',
  encoding: null,
  fd: null,
  mode: 0o666 }

options可以包含一個(gè)start選項(xiàng)來(lái)允許從指定位置開(kāi)始寫(xiě)入數(shù)據(jù)。修改一個(gè)文件而不是替換它,需要一個(gè)r+標(biāo)識(shí),而不是默認(rèn)的w。編碼可以是'utf8','ascii','binary''base64'。

與上文的ReadStream類(lèi)似,如果指定了fd,可寫(xiě)流會(huì)忽略path參數(shù),并且使用指定的文件描述符。這意味open事件不再會(huì)觸發(fā)。

如果options是一個(gè)字符串,那么它表示指定的編碼。

Class: fs.WriteStream

WriteStream是一個(gè)可寫(xiě)流。

Event: 'open'

  • fd Integer WriteStream使用的文件描述符

當(dāng)可寫(xiě)流文件被打開(kāi)時(shí)觸發(fā)。

file.bytesWritten

至今為止寫(xiě)入的字節(jié)數(shù)。不包括仍在寫(xiě)入隊(duì)列中的數(shù)據(jù)。

Class: fs.FSWatcher

fs.watch()返回的對(duì)象。

watcher.close()

停止在指定的fs.FSWatcher上監(jiān)視文件變化。

Event: 'change'

  • event String 文件的改變類(lèi)型
  • filename String The filename that changed (if relevant/available)被改變的文件(如果有意義/可用的話)

當(dāng)被監(jiān)視的目錄或文件發(fā)生了改變時(shí)觸發(fā)。詳情參閱fs.watch。

Event: 'error'

  • error Error object

當(dāng)錯(cuò)誤發(fā)生時(shí)觸發(fā)。

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)