Node.js fs 模塊

2021-09-15 16:31 更新

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

readFileSync()

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

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

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

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

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

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

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

writeFileSync()

writeFileSync方法用于同步寫入文件。

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

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

exists(path, callback)

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

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

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

需要注意的是,不要在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接受三個參數(shù),第一個是目錄名,第二個是權(quán)限值,第三個是回調(diào)函數(shù)。

writeFile方法用于寫入文件。

var fs = require('fs');

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

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方法的第一個參數(shù)是文件名,第二個參數(shù)是文件編碼,第三個參數(shù)是回調(diào)函數(shù)??捎玫奈募幋a包括“ascii”、“utf8”和“base64”。如果沒有指定文件編碼,返回的是原始的緩存二進制數(shù)據(jù),這時需要調(diào)用buffer對象的toString方法,將其轉(zhuǎn)為字符串。

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

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

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

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

mkdirSync(),writeFileSync(),readFileSync()

這三個方法是建立目錄、寫入文件、讀取文件的同步版本。

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

對于流量較大的服務(wù)器,最好還是采用異步操作,因為同步操作時,只有前一個操作結(jié)束,才會開始后一個操作,如果某個操作特別耗時(常常發(fā)生在讀寫數(shù)據(jù)時),會導(dǎo)致整個程序停頓。

readdir()

readdir方法用于讀取目錄,返回一個所包含的文件和子目錄的數(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) {
        // 對所有文件進行處理
      }
    });
  });
});

stat()

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

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)聽一個文件,如果該文件發(fā)生變化,就會自動觸發(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方法用于解除對文件的監(jiān)聽。

createReadStream()

createReadStream方法往往用于打開大型的文本文件,創(chuàng)建一個讀取操作的數(shù)據(jù)流。所謂大型文本文件,指的是文本文件的體積很大,讀取操作的緩存裝不下,只能分成幾次發(fā)送,每次發(fā)送會觸發(fā)一個data事件,發(fā)送結(jié)束會觸發(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)建一個寫入數(shù)據(jù)流對象,該對象的write方法用于寫入數(shù)據(jù),end方法用于結(jié)束寫入操作。

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

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號