Node.js fs 模塊

2021-09-15 16:31 更新

fs是filesystem的縮寫(xiě),該模塊提供本地文件的讀寫(xiě)能力,基本上是POSIX文件操作命令的簡(jiǎn)單包裝。但是,這個(gè)模塊幾乎對(duì)所有操作提供異步和同步兩種操作方式,供開(kāi)發(fā)者選擇。

readFileSync()

readFileSync方法用于同步讀取文件,返回一個(gè)字符串。

var text = fs.readFileSync(fileName, "utf8");

// 將文件按行拆成數(shù)組
text.split(/\r?\n/).forEach(function (line) {
  // ...
});

該方法的第一個(gè)參數(shù)是文件路徑,第二個(gè)參數(shù)是文本文件編碼,默認(rèn)為utf8。

不同系統(tǒng)的行結(jié)尾字符不同,可以用下面的方法判斷。

// 方法一,查詢現(xiàn)有的行結(jié)尾字符
var EOL = fileContents.indexOf("\r\n") >= 0 ? "\r\n" : "\n";

// 方法二,根據(jù)當(dāng)前系統(tǒng)處理
var EOL = (process.platform === 'win32' ? '\r\n' : '\n')

writeFileSync()

writeFileSync方法用于同步寫(xiě)入文件。

fs.writeFileSync(fileName, str, 'utf8');

它的第一個(gè)參數(shù)是文件路徑,第二個(gè)參數(shù)是寫(xiě)入文件的字符串,第三個(gè)參數(shù)是文件編碼,默認(rèn)為utf8。

exists(path, callback)

exists方法用來(lái)判斷給定路徑是否存在,然后不管結(jié)果如何,都會(huì)調(diào)用回調(diào)函數(shù)。

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

上面代碼表明,回調(diào)函數(shù)的參數(shù)是一個(gè)表示文件是否存在的布爾值。

需要注意的是,不要在open方法之前調(diào)用exists方法,open方法本身就能檢查文件是否存在。

下面的例子是如果給定目錄存在,就刪除它。

if(fs.exists(outputFolder)) {
  console.log("Removing "+outputFolder);
  fs.rmdir(outputFolder);
}

mkdir(),writeFile(),readfile()

mkdir方法用于新建目錄。

var fs = require('fs');

fs.mkdir('./helloDir',0777, function (err) {
  if (err) throw err;
});

mkdir接受三個(gè)參數(shù),第一個(gè)是目錄名,第二個(gè)是權(quán)限值,第三個(gè)是回調(diào)函數(shù)。

writeFile方法用于寫(xiě)入文件。

var fs = require('fs');

fs.writeFile('./helloDir/message.txt', 'Hello Node', function (err) {
  if (err) throw err;
  console.log('文件寫(xiě)入成功');
});

readfile方法用于讀取文件內(nèi)容。

var fs = require('fs');

fs.readFile('./helloDir/message.txt','UTF-8' ,function (err, data) {
  if (err) throw err;
  console.log(data);
});

上面代碼使用readFile方法讀取文件。readFile方法的第一個(gè)參數(shù)是文件名,第二個(gè)參數(shù)是文件編碼,第三個(gè)參數(shù)是回調(diào)函數(shù)??捎玫奈募幋a包括“ascii”、“utf8”和“base64”。如果沒(méi)有指定文件編碼,返回的是原始的緩存二進(jìn)制數(shù)據(jù),這時(shí)需要調(diào)用buffer對(duì)象的toString方法,將其轉(zhuǎn)為字符串。

var fs = require('fs');
fs.readFile('example_log.txt', function (err, logData) {
  if (err) throw err;
  var text = logData.toString();
});

readFile方法是異步操作,所以必須小心,不要同時(shí)發(fā)起多個(gè)readFile請(qǐng)求。

for(var i = 1; i <= 1000; i++) {
  fs.readFile('./'+i+'.txt', function() {
     // do something with the file
  });
}

上面代碼會(huì)同時(shí)發(fā)起1000個(gè)readFile異步請(qǐng)求,很快就會(huì)耗盡系統(tǒng)資源。

mkdirSync(),writeFileSync(),readFileSync()

這三個(gè)方法是建立目錄、寫(xiě)入文件、讀取文件的同步版本。

fs.mkdirSync('./helloDirSync',0777);
fs.writeFileSync('./helloDirSync/message.txt', 'Hello Node');
var data = fs.readFileSync('./helloDirSync/message.txt','UTF-8');
console.log('file created with contents:');
console.log(data);

對(duì)于流量較大的服務(wù)器,最好還是采用異步操作,因?yàn)橥讲僮鲿r(shí),只有前一個(gè)操作結(jié)束,才會(huì)開(kāi)始后一個(gè)操作,如果某個(gè)操作特別耗時(shí)(常常發(fā)生在讀寫(xiě)數(shù)據(jù)時(shí)),會(huì)導(dǎo)致整個(gè)程序停頓。

readdir()

readdir方法用于讀取目錄,返回一個(gè)所包含的文件和子目錄的數(shù)組。

fs.readdir(process.cwd(), function (err, files) {
  if (err) {
    console.log(err);
    return;
  }

  var count = files.length;
  var results = {};
  files.forEach(function (filename) {
    fs.readFile(filename, function (data) {
      results[filename] = data;
      count--;
      if (count <= 0) {
        // 對(duì)所有文件進(jìn)行處理
      }
    });
  });
});

stat()

stat方法的參數(shù)是一個(gè)文件或目錄,它產(chǎn)生一個(gè)對(duì)象,該對(duì)象包含了該文件或目錄的具體信息。我們往往通過(guò)該方法,判斷正在處理的到底是一個(gè)文件,還是一個(gè)目錄。

var fs = require('fs');

fs.readdir('/etc/', function (err, files) {
  if (err) throw err;

  files.forEach( function (file) {
    fs.stat('/etc/' + file, function (err, stats) {
      if (err) throw err;

      if (stats.isFile()) {
        console.log("%s is file", file);
      }
      else if (stats.isDirectory ()) {
      console.log("%s is a directory", file);
      }    
    console.log('stats:  %s',JSON.stringify(stats));
    });
  });
});

watchfile(),unwatchfile()

watchfile方法監(jiān)聽(tīng)一個(gè)文件,如果該文件發(fā)生變化,就會(huì)自動(dòng)觸發(fā)回調(diào)函數(shù)。

var fs = require('fs');

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

fs.writeFile('./testFile.txt', "changed", function (err) {
  if (err) throw err;

  console.log("file write complete");   
});

unwatchfile方法用于解除對(duì)文件的監(jiān)聽(tīng)。

createReadStream()

createReadStream方法往往用于打開(kāi)大型的文本文件,創(chuàng)建一個(gè)讀取操作的數(shù)據(jù)流。所謂大型文本文件,指的是文本文件的體積很大,讀取操作的緩存裝不下,只能分成幾次發(fā)送,每次發(fā)送會(huì)觸發(fā)一個(gè)data事件,發(fā)送結(jié)束會(huì)觸發(fā)end事件。

var fs = require('fs');

function readLines(input, func) {
  var remaining = '';

  input.on('data', function(data) {
    remaining += data;
    var index = remaining.indexOf('\n');
    var last  = 0;
    while (index > -1) {
      var line = remaining.substring(last, index);
      last = index + 1;
      func(line);
      index = remaining.indexOf('\n', last);
    }

    remaining = remaining.substring(last);
  });

  input.on('end', function() {
    if (remaining.length > 0) {
      func(remaining);
    }
  });
}

function func(data) {
  console.log('Line: ' + data);
}

var input = fs.createReadStream('lines.txt');
readLines(input, func);

createWriteStream()

createWriteStream方法創(chuàng)建一個(gè)寫(xiě)入數(shù)據(jù)流對(duì)象,該對(duì)象的write方法用于寫(xiě)入數(shù)據(jù),end方法用于結(jié)束寫(xiě)入操作。

var out = fs.createWriteStream(fileName, { encoding: "utf8" });
out.write(str);
out.end();
以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

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

編程獅公眾號(hào)