最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

使用nodeJS中的fs模塊對(duì)文件及目錄進(jìn)行讀寫,刪除,追加,等操作詳解

 更新時(shí)間:2020年02月06日 14:09:42   作者:小火柴的藍(lán)色理想  
nodeJS中fs模塊對(duì)系統(tǒng)文件及目錄進(jìn)行讀寫操作,本文將詳細(xì)介紹nodejs中的文件操作模塊fs的使用方法

fs概述

文件 I/O 是由簡單封裝的標(biāo)準(zhǔn) POSIX 函數(shù)提供的。 nodeJS中通過 require('fs') 使用fs模塊。 所有的方法都有異步和同步的形式。

異步形式始終以完成回調(diào)作為它最后一個(gè)參數(shù)。 傳給完成回調(diào)的參數(shù)取決于具體方法,但第一個(gè)參數(shù)總是留給異常。 如果操作成功完成,則第一個(gè)參數(shù)會(huì)是 null 或 undefined

//異步示例
var fs = require('fs');
fs.unlink('/tmp/hello', function(err){
 if (err) throw err;
 console.log('successfully deleted /tmp/hello');
});

當(dāng)使用同步形式時(shí),任何異常都會(huì)被立即拋出。 可以使用 try/catch 來處理異常,或讓它們往上冒泡

//同步示例
var fs = require('fs');
fs.unlinkSync('/tmp/hello');
console.log('successfully deleted /tmp/hello');

異步方法不保證執(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.stat 可能在 fs.rename 之前執(zhí)行。正確的方法是把回調(diào)鏈起來

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

推薦開發(fā)者使用這些函數(shù)的異步版本。 同步版本會(huì)阻塞整個(gè)進(jìn)程,直到它們完成(停止所有連接)

fs底層操作

1、打開文件 fs.open(path, flags[, mode], callback)

參數(shù)如下:

path <String> | <Buffer>

flags <String> | <Number>

mode <Integer> 設(shè)置文件模式(權(quán)限和 sticky 位),但只有當(dāng)文件被創(chuàng)建時(shí)才有效。默認(rèn)為 0666,可讀寫

callback <Function> 該回調(diào)有兩個(gè)參數(shù) (err錯(cuò)誤, fd文件標(biāo)識(shí),與定時(shí)器標(biāo)識(shí)類似)

flags可以是:

'r' - 以讀取模式打開文件。如果文件不存在則發(fā)生異常。

'r+' - 以讀寫模式打開文件。如果文件不存在則發(fā)生異常。

'rs+' - 以同步讀寫模式打開文件。命令操作系統(tǒng)繞過本地文件系統(tǒng)緩存。

'w' - 以寫入模式打開文件。文件會(huì)被創(chuàng)建(如果文件不存在)或截?cái)?如果文件存在)。

'wx' - 類似 'w',但如果 path 存在,則失敗。

'w+' - 以讀寫模式打開文件。文件會(huì)被創(chuàng)建(如果文件不存在)或截?cái)?如果文件存在)。

'wx+' - 類似 'w+',但如果 path 存在,則失敗。

'a' - 以追加模式打開文件。如果文件不存在,則會(huì)被創(chuàng)建。

'ax' - 類似于 'a',但如果 path 存在,則失敗。

'a+' - 以讀取和追加模式打開文件。如果文件不存在,則會(huì)被創(chuàng)建。

'ax+' - 類似于 'a+',但如果 path 存在,則失敗。

[注意]使用'rs+'模式不會(huì)使fs.open()進(jìn)入同步阻塞調(diào)用。如果那是你想要的,則應(yīng)該使用fs.openSync()

var fs = require('fs');

fs.open('a.txt','r',function(err,fs){

  console.log(err);//null

  console.log(fs);//3

})
var fs = require('fs');
fs.open('b.txt','r',function(err,fs){
/*
{ Error: ENOENT: no such file or directory, open 'D:\project\b.txt'
  at Error (native)
 errno: -4058,
 code: 'ENOENT',
 syscall: 'open',
 path: 'D:\\project\\b.txt' }
 */
  console.log(err);
  console.log(fs);//undefined
})

文件的回調(diào)函數(shù)中的第二個(gè)參數(shù)fd代表文件標(biāo)識(shí),與定時(shí)器標(biāo)識(shí)類似,用于標(biāo)識(shí)文件,且隨著文件的打開順序遞增

var fs = require('fs');

fs.open('1.txt','r',function(err,fs){

  console.log(fs);//3

})

fs.open('2.txt','r',function(err,fs){

  console.log(fs);//4

})

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

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

var fs = require('fs');

var result = fs.openSync('1.txt','r');

console.log(result);//3

2、讀取文件 fs.read(fd, buffer, offset, length, position, callback)

參數(shù)如下:

fd <Integer> 通過 fs.open() 方法返回的文件描述符

buffer <String> | <Buffer> 數(shù)據(jù)將被寫入到buffer

offset <Integer> buffer中開始寫入的偏移量

length <Integer> 指定要讀取的字節(jié)數(shù)(整數(shù))

position <Integer> 指定從文件中開始讀取的位置(整數(shù))。 如果position為null,則數(shù)據(jù)從當(dāng)前文件位置開始讀取

callback <Function> 回調(diào)有三個(gè)參數(shù) (err, bytesRead, buffer)。err為錯(cuò)誤信息,bytesRead表示讀取的字節(jié)數(shù),buffer為緩沖區(qū)對(duì)象

由于使用read()方法,會(huì)將文件內(nèi)容讀取buffer對(duì)象中,所以需要提前先準(zhǔn)備一個(gè)buffer對(duì)象

var fs = require('fs');
fs.open('1.txt','r',function(err,fd){
  if(err){
    console.log('文件打開失敗');
  }else{
    var bf = Buffer.alloc(5);
    fs.read(fd,bf,0,3,null,function(err,len,buffer){
      console.log(err);//null
      console.log(len);//3
      console.log(buffer);//<Buffer 61 61 61 00 00>
    })
  }
});

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

fs.read() 的同步版本,返回 bytesRead 的數(shù)量

var fs = require('fs');

var fd = fs.openSync('1.txt','r');

var bf = Buffer.alloc(5);

var result = fs.readSync(fd,bf,0,3,null);

console.log(result);//3

3、寫入文件 fs.write(fd, buffer, offset, length[, position], callback)

參數(shù)如下

fd <Integer>  文件標(biāo)識(shí)

buffer <String> | <Buffer> 要將buffer中的數(shù)據(jù)寫入到文件中

offset <Integer> buffer對(duì)象中要寫入的數(shù)據(jù)的起始位置

length <Integer> length是一個(gè)整數(shù),指定要寫入的字節(jié)數(shù)

position <Integer> 指定從文件開始寫入數(shù)據(jù)的位置的偏移量。 如果 typeof position !== 'number',則數(shù)據(jù)從當(dāng)前位置寫入

callback <Function> 回調(diào)有三個(gè)參數(shù)(err, written, buffer),其中written指定從buffer寫入了多少字節(jié)

[注意]多次對(duì)同一文件使用fs.write且不等待回調(diào),是不安全的。對(duì)于這種情況,強(qiáng)烈推薦使用 fs.createWriteStream

當(dāng)我們要對(duì)打開的文件進(jìn)行寫操作的時(shí)候,打開文件的模式應(yīng)該是讀寫模式

var fs = require('fs');
fs.open('1.txt','r+',function(err,fd){
  if(err){
    console.log('文件打開失敗');
  }else{
    var bf = Buffer.from('test');
    fs.write(fd,bf,0,3,null,function(err,len,buffer){
      console.log(err);//null
      console.log(len);//3
      console.log(buffer);//<Buffer 74 65 73 74>
    })
  }
});

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

該方法寫入data到fd指定的文件。如果data不是一個(gè)Buffer實(shí)例,則該值將被強(qiáng)制轉(zhuǎn)換為一個(gè)字符串

不同于寫入 buffer,該方法整個(gè)字符串必須被寫入。不能指定子字符串,這是因?yàn)榻Y(jié)果數(shù)據(jù)的字節(jié)偏移量可能與字符串的偏移量不同

fd  <Integer> 文件標(biāo)識(shí)

data <String> | <Buffer> 要將string或buffer中的數(shù)據(jù)寫入到文件中

position <Integer> 指向從文件開始寫入數(shù)據(jù)的位置的偏移量。 如果 typeof position !== 'number',則數(shù)據(jù)從當(dāng)前位置寫入

encoding <String> 期望的字符串編碼

callback <Function> 回調(diào)有三個(gè)參數(shù)(err, written, str),其中written指定從str寫入了多少字節(jié)

var fs = require('fs');
fs.open('1.txt','r+',function(err,fd){
  if(err){
    console.log('文件打開失敗');
  }else{
    fs.write(fd,'12345',function(err,len,str){
      console.log(err);//null
      console.log(len);//5
      console.log(str);//<Buffer 74 65 73 74>
    })
  }
});

fs.writeSync()

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

var fs = require('fs');
var fd = fs.openSync('1.txt','r+');
var bf = Buffer.alloc(5);
var result = fs.writeSync(fd,bf,0,3,null);
console.log(result);//3

4、關(guān)閉文件 fs.close(fd, callback)

一個(gè)文件被操作后,要及時(shí)將該文件關(guān)閉

參數(shù)如下:

fd - 通過 fs.open() 方法返回的文件描述符。

callback - 回調(diào)函數(shù),沒有參數(shù)。

var fs = require('fs');
fs.open('1.txt','r+',function(err,fd){
  if(err){
    console.log('文件打開失敗');
  }else{
    fs.close(fd, function(err){
      if (err){
        console.log(err);
      } 
      console.log("文件關(guān)閉成功");
    });
  }
});

fs.closeSync(fd)

fs.close(fd, callback)的同步版本,返回undefined

var fs = require('fs');

var fd = fs.openSync('1.txt','r+');

fs.closeSync(fd);

File操作

上一部分介紹的都是些底層的操作,接下來將介紹一些更便捷的文件操作。使用下列方法的時(shí)候,不需要再打開和關(guān)閉文件,直接操作即可

1、寫入文件

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

異步的將數(shù)據(jù)寫入一個(gè)文件,如果文件不存在則新建,如果文件原先存在,會(huì)被替換

參數(shù)如下:

file - 文件名或文件描述符。

data - 要寫入文件的數(shù)據(jù),可以是 String(字符串) 或 Buffer(流) 對(duì)象。

options - 該參數(shù)是一個(gè)對(duì)象,包含 {encoding, mode, flag}。默認(rèn)編碼為 utf8, 模式為 0666 , flag 為 'w'

callback - 回調(diào)函數(shù),回調(diào)函數(shù)只包含錯(cuò)誤信息參數(shù)(err),在寫入失敗時(shí)返回。

var fs = require('fs');

var filename = '1.txt';

fs.writeFile(filename,'hello',function(err){

  console.log(err);//null

})

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

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

var fs = require('fs');

var filename = '1.txt';

fs.writeFileSync(filename,'abc');

2、追加文件

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

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

參數(shù)如下

file - 文件名或文件描述符。

data - 要寫入文件的數(shù)據(jù),可以是 String(字符串) 或 Buffer(流) 對(duì)象。

options - 該參數(shù)是一個(gè)對(duì)象,包含 {encoding, mode, flag}。默認(rèn)編碼為 utf8, 模式為 0666 , flag 為 'w'

callback - 回調(diào)函數(shù),回調(diào)函數(shù)只包含錯(cuò)誤信息參數(shù)(err),在寫入失敗時(shí)返回。

var fs = require('fs');

var filename = '1.txt';

fs.appendFile(filename,' world',function(err){

  console.log(err);//null

})

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

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

var fs = require('fs');

var filename = '1.txt';

fs.appendFileSync(filename,' lalala');

3、讀取文件

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

參數(shù)如下

file - 文件名或文件描述符

options - 該參數(shù)是一個(gè)對(duì)象,包含 {encoding, flag}。默認(rèn)編碼為null,即如果字符編碼未指定,則返回原始的 buffer;flag默認(rèn)為'r'

callback - 回調(diào)函數(shù),回調(diào)有兩個(gè)參數(shù) (err, data),其中data是文件的內(nèi)容(buffer對(duì)象),err是錯(cuò)誤信息參數(shù),在寫入失敗時(shí)返回

var fs = require('fs');
var filename = '1.txt';
fs.readFile(filename,function(err,data){
  if(err){
    console.log('文件讀取失敗');
  }else{
    console.log(data);//<Buffer 61 62 63 20 77 6f 72 6c 64 20 6c 61 6c 61 6c 61>
    console.log(data.toString());//'abc world lalala'
  }
});

fs.readFileSync(file[, options])

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

如果指定了encoding選項(xiàng),則該函數(shù)返回一個(gè)字符串,否則返回一個(gè)buffer

var fs = require('fs');
var filename = '1.txt';
var result = fs.readFileSync(filename);
console.log(result);//<Buffer 61 62 63 20 77 6f 72 6c 64 20 6c 61 6c 61 6c 61>
console.log(result.toString());'abc world lalala'

4、刪除文件

fs.unlink(path, callback)

參數(shù)如下:

path - 文件路徑。

callback - 回調(diào)函數(shù),沒有參數(shù)。

var fs = require('fs');
var filename = '1.txt';
fs.unlink(filename, function(err) {
  if (err) {
    return console.log('刪除失敗');
  }
  console.log("刪除成功");
});

fs.unlinkSync(path)

fs.unlink(path, callback)的同步版本,返回值為undefined

var fs = require('fs');

var filename = '1.txt';

fs.unlink(filename);

5、重命名

fs.rename(oldPath, newPath, callback)

參數(shù)如下:

oldPath <String> | <Buffer>

newPath <String> | <Buffer>

callback <Function> 回調(diào)只有一個(gè)可能的異常參數(shù)

var fs = require('fs');
var filename = 'a.txt';
fs.rename(filename,'2.new.txt',function(err){
  console.log(err);//null
})

fs.renameSync(oldPath, newPath)

fs.rename(oldPath, newPath, callback)的同步版本,返回undefined

var fs = require('fs');

var filename = '2.new.txt';

var result = fs.renameSync(filename,'a.txt');

6、文件信息

fs.stat(path, callback)

fs.stat()執(zhí)行后,會(huì)將stats類的實(shí)例返回給其回調(diào)函數(shù)??赏ㄟ^stats類中的提供方法判斷文件的相關(guān)屬性

參數(shù)如下:

path - 文件路徑。

callback - 回調(diào)函數(shù),帶有兩個(gè)參數(shù)如:(err, stats), stats 是 fs.Stats 對(duì)象

var fs = require('fs');
var filename = 'a.txt';
fs.stat(filename,function(err,stats){
  console.log(err);//null
/*
{ dev: 223576,
 mode: 33206,
 nlink: 1,
 uid: 0,
 gid: 0,
 rdev: 0,
 blksize: undefined,
 ino: 7599824371527537,
 size: 0,
 blocks: undefined,
 atime: 2017-06-03T14:18:15.370Z,
 mtime: 2017-06-03T14:18:15.370Z,
 ctime: 2017-06-03T16:32:05.776Z,
 birthtime: 2017-06-03T14:18:15.370Z }
 */  
  console.log(stats);
});

stats類中的方法有

stats.isFile()  如果是文件返回 true,否則返回 false。

stats.isDirectory() 如果是目錄返回 true,否則返回 false。

stats.isBlockDevice()   如果是塊設(shè)備返回 true,否則返回 false。

stats.isCharacterDevice()   如果是字符設(shè)備返回 true,否則返回 false。

stats.isSymbolicLink()  如果是軟鏈接返回 true,否則返回 false。

stats.isFIFO()  如果是FIFO,返回true,否則返回false。FIFO是UNIX中的一種特殊類型的命令管道。

stats.isSocket()    如果是 Socket 返回 true,否則返回 false。

var fs = require('fs');
var filename = 'a.txt';
fs.stat(filename,function(err,stats){
  console.log(stats.isFile());//true
});

fs.statSync(path)

fs.stat(path, callback)方法的同步版本,返回一個(gè) fs.Stats 實(shí)例

var fs = require('fs');
var filename = 'a.txt';
var result = fs.statSync(filename);
/*
{ dev: 223576,
 mode: 33206,
 nlink: 1,
 uid: 0,
 gid: 0,
 rdev: 0,
 blksize: undefined,
 ino: 7599824371527537,
 size: 0,
 blocks: undefined,
 atime: 2017-06-03T14:18:15.370Z,
 mtime: 2017-06-03T14:18:15.370Z,
 ctime: 2017-06-03T16:32:05.776Z,
 birthtime: 2017-06-03T14:18:15.370Z }
 */
console.log(result);

7、監(jiān)聽

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

該方法用于監(jiān)視filename的變化,filename可以是一個(gè)文件或一個(gè)目錄。返回的對(duì)象是一個(gè)fs.FSWatcher

參數(shù)如下

filename <String> | <Buffer>

options <String> | <Object> 參數(shù)可選,如果options是一個(gè)字符串,則它指定了encoding。否則options應(yīng)該以一個(gè)對(duì)象傳入

    persistent <Boolean> 指明如果文件正在被監(jiān)視,進(jìn)程是否應(yīng)該繼續(xù)運(yùn)行。默認(rèn)為true

    recursive <Boolean> 指明是否全部子目錄應(yīng)該被監(jiān)視,或只是當(dāng)前目錄。 適用于當(dāng)一個(gè)目錄被指定時(shí),且只在支持的平臺(tái)。默認(rèn)為false

    encoding <String> 指定用于傳給監(jiān)聽器的文件名的字符編碼。默認(rèn)為'utf8'

listener <Function> 回調(diào)函數(shù)有兩個(gè)參數(shù) (eventType, filename)。 eventType可以是'rename'或'change',filename是觸發(fā)事件的文件的名稱

回調(diào)中提供的 filename 參數(shù)僅在 Linux 和 Windows 系統(tǒng)上支持。 即使在支持的平臺(tái)中,filename 也不能保證提供。 因此,不要以為 filename 參數(shù)總是在回調(diào)中提供,如果它是空的,需要有一定的后備邏輯

fs.watch('somedir', (eventType, filename) => {
 console.log(`事件類型是: ${eventType}`);
 if (filename) {
  console.log(`提供的文件名: ${filename}`);
 } else {
  console.log('未提供文件名');
 }
});
var fs = require('fs');
var filename = '1.txt';
fs.watch(filename,function(eventType, _filename){
  console.log(eventType);//change
  if(_filename){
    console.log(_filename + '發(fā)生了改變');//'1.txt發(fā)生了改變'
  }else{
    console.log('...');
  }
  
})

[注意]當(dāng)一個(gè)文件出現(xiàn)或消失在一個(gè)目錄里時(shí),'rename'也會(huì)被觸發(fā)

fs目錄操作

1、創(chuàng)建

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

參數(shù)如下:

path - 文件路徑。

mode - 設(shè)置目錄權(quán)限,默認(rèn)為 0777。

callback - 回調(diào)函數(shù),回調(diào)只有一個(gè)可能的異常參數(shù)

var fs = require('fs');
fs.mkdir('./1',function(err){
  console.log(err);//null
})

fs.mkdirSync(path[, mode])

fs.mkdir(path[, mode], callback)的同步版本,返回undefined

var fs = require('fs');
fs.mkdirSync('./2');

2、刪除

fs.rmdir(path, callback)

參數(shù)如下:

path - 文件路徑。

callback - 回調(diào)函數(shù),回調(diào)只有一個(gè)可能的異常參數(shù)

var fs = require('fs');
fs.rmdir('./1',function(err){
  console.log(err);//null
})

fs.rmdirSync(path, callback)

fs.rmdir(path, callback)的同步版本,返回undefined

var fs = require('fs');
fs.rmdirSync('./2');

3、讀取

fs.readdir(path[, options], callback)

參數(shù)如下:

path <String> | <Buffer>

options <String> | <Object> 可選的 options 參數(shù)用于傳入回調(diào)的文件名,它可以是一個(gè)字符串并指定一個(gè)字符編碼,或是一個(gè)對(duì)象且由一個(gè) encoding 屬性指定使用的字符編碼。 如果 encoding 設(shè)為 'buffer',則返回的文件名會(huì)被作為 Buffer 對(duì)象傳入

    encoding <String> 默認(rèn) = 'utf8'

callback <Function> 回調(diào)有兩個(gè)參數(shù) (err, files),其中 files 是目錄中不包括 '.' 和 '..' 的文件名的數(shù)組

var fs = require('fs');
fs.readdir('./',function(err,data){
  console.log(err);//null
/*
[ '.csslintrc',
 '.jshintrc',
 'a.txt',
 'dist',
 'Gruntfile.js',
 'Gruntfile1.js',
 'index.html',
 'main.js',
 'node_modules',
 'package.json',
 'src' ]
 */
  console.log(data);
})
var fs = require('fs');
fs.readdir('./',function(err,data){
  data.forEach(function(item,index,arr){
    fs.stat(item,function(err,stats){
      if(stats.isFile()){
        console.log('文件:' + item);
      }
      if(stats.isDirectory()){
        console.log('目錄:' + item);
      }
    });  
  })
})
/*
文件:.jshintrc
文件:.csslintrc
目錄:dist
文件:Gruntfile.js
文件:index.html
文件:Gruntfile1.js
文件:main.js
目錄:node_modules
文件:package.json
文件:a.txt
目錄:src
 */

fs.readdirSync(path[, options], callback)

fs.readdir(path[, options], callback)的同步版本,返回一個(gè)不包括 '.' 和 '..' 的文件名的數(shù)組

var fs = require('fs');
var result = fs.readdirSync('./');
/*
[ '.csslintrc',
 '.jshintrc',
 'a.txt',
 'dist',
 'Gruntfile.js',
 'Gruntfile1.js',
 'index.html',
 'main.js',
 'node_modules',
 'package.json',
 'src' ]
 */
console.log(result);

遍歷目錄

遍歷目錄是操作文件時(shí)的一個(gè)常見需求。比如寫一個(gè)程序,需要找到并處理指定目錄下的所有JS文件時(shí),就需要遍歷整個(gè)目錄

遍歷目錄時(shí)一般使用遞歸算法,否則就難以編寫出簡潔的代碼。遞歸算法與數(shù)學(xué)歸納法類似,通過不斷縮小問題的規(guī)模來解決問題

function factorial(n) {
  if (n === 1) {
    return 1;
  } else {
    return n * factorial(n - 1);
  }
}

上邊的函數(shù)用于計(jì)算N的階乘(N!)??梢钥吹剑?dāng)N大于1時(shí),問題簡化為計(jì)算N乘以N-1的階乘。當(dāng)N等于1時(shí),問題達(dá)到最小規(guī)模,不需要再簡化,因此直接返回1

目錄是一個(gè)樹狀結(jié)構(gòu),在遍歷時(shí)一般使用深度優(yōu)先+先序遍歷算法。深度優(yōu)先,意味著到達(dá)一個(gè)節(jié)點(diǎn)后,首先接著遍歷子節(jié)點(diǎn)而不是鄰居節(jié)點(diǎn)。先序遍歷,意味著首次到達(dá)了某節(jié)點(diǎn)就算遍歷完成,而不是最后一次返回某節(jié)點(diǎn)才算數(shù)。因此使用這種遍歷方式時(shí),下邊這棵樹的遍歷順序是A > B > D > E > C > F

          A

         / \

        B   C

       / \   \

      D   E   F

了解了必要的算法后,我們可以簡單地實(shí)現(xiàn)以下目錄遍歷函數(shù)

function travel(dir, callback) {
  fs.readdirSync(dir).forEach(function (file) {
    var pathname = path.join(dir, file);
    if (fs.statSync(pathname).isDirectory()) {
      travel(pathname, callback);
    } else {
      callback(pathname);
    }
  });
}

可以看到,該函數(shù)以某個(gè)目錄作為遍歷的起點(diǎn)。遇到一個(gè)子目錄時(shí),就先接著遍歷子目錄。遇到一個(gè)文件時(shí),就把文件的絕對(duì)路徑傳給回調(diào)函數(shù)?;卣{(diào)函數(shù)拿到文件路徑后,就可以做各種判斷和處理。因此假設(shè)有以下目錄

- /home/user/

    - foo/

        x.js

    - bar/

        y.js

    z.css

使用以下代碼遍歷該目錄時(shí),得到的輸入如下

travel('/home/user', function (pathname) {
  console.log(pathname);
});
------------------------
/home/user/foo/x.js
/home/user/bar/y.js
/home/user/z.css

如果讀取目錄或讀取文件狀態(tài)時(shí)使用的是異步API,目錄遍歷函數(shù)實(shí)現(xiàn)起來會(huì)有些復(fù)雜,但原理完全相同。travel函數(shù)的異步版本如下

function travel(dir, callback, finish) {
  fs.readdir(dir, function (err, files) {
    (function next(i) {
      if (i < files.length) {
        var pathname = path.join(dir, files[i]);
        fs.stat(pathname, function (err, stats) {
          if (stats.isDirectory()) {
            travel(pathname, callback, function () {
              next(i + 1);
            });
          } else {
            callback(pathname, function () {
              next(i + 1);
            });
          }
        });
      } else {
        finish && finish();
      }
    }(0));
  });

更多關(guān)于nodeJS中fs模塊對(duì)文件及目錄進(jìn)行讀寫,刪除,追加,等操作的相關(guān)文章大家可以查看下面的相關(guān)鏈接

相關(guān)文章

  • 初識(shí)Node.js

    初識(shí)Node.js

    本文主要是簡單講訴了Node.js的介紹,安裝,希望對(duì)剛剛接觸Node.js的同學(xué)能有所幫助,有什么問題可以給我留言,一起學(xué)習(xí)進(jìn)步
    2014-09-09
  • node.js中Socket.IO的進(jìn)階使用技巧

    node.js中Socket.IO的進(jìn)階使用技巧

    這篇文章主要介紹了node.js中Socket.IO的進(jìn)階使用技巧,本文講解了配置、房間、事件、授權(quán)等內(nèi)容,需要的朋友可以參考下
    2014-11-11
  • 基于 Docker 開發(fā) NodeJS 應(yīng)用

    基于 Docker 開發(fā) NodeJS 應(yīng)用

    這是兩篇文章的第一篇。本文涵蓋了有關(guān)在使用 Express 框架開發(fā)一個(gè)Node應(yīng)用時(shí),用Docker 替代 Vagrant 的比較詳細(xì)的教程, 應(yīng)用將使用 connect-redis 中間件將會(huì)話信息持久化到Redis中. 第二篇文章將介紹到將這個(gè)開發(fā)的設(shè)置產(chǎn)品化.
    2014-07-07
  • 快速了解Node中的Stream流是什么

    快速了解Node中的Stream流是什么

    今天小編就為大家分享一篇關(guān)于快速了解Node中的Stream流是什么,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2019-02-02
  • 解決下載了nodejs但npm?-v沒有反應(yīng)問題的全過程

    解決下載了nodejs但npm?-v沒有反應(yīng)問題的全過程

    最近工作中遇到了個(gè)問題,node安裝成功,但npm無法使用,所以下面這篇文章主要給大家介紹了關(guān)于下載了nodejs但npm?-v沒有反應(yīng)問題解決的相關(guān)資料,需要的朋友可以參考下
    2022-08-08
  • Nodejs Stream 數(shù)據(jù)流使用手冊(cè)

    Nodejs Stream 數(shù)據(jù)流使用手冊(cè)

    這篇文章主要介紹了Nodejs Stream 數(shù)據(jù)流使用手冊(cè)的相關(guān)資料,感興趣的小伙伴一起學(xué)習(xí)吧
    2016-04-04
  • 初始Nodejs

    初始Nodejs

    本文屬于nodejs的基礎(chǔ)知識(shí)介紹篇,從nodejs的基本概念,到架構(gòu)示意圖,同步異步等方面做了詳細(xì)的解答,是篇非常不錯(cuò)的文章
    2014-11-11
  • connect中間件session、cookie的使用方法分享

    connect中間件session、cookie的使用方法分享

    今天大象哥用了下connect的session和cookie,感覺還挺好用的,分享一下(里面坑挺多的,文檔寫的太模糊了,費(fèi)了哥不少時(shí)間)。
    2014-06-06
  • gulp加批處理(.bat)實(shí)現(xiàn)ng多應(yīng)用一鍵自動(dòng)化構(gòu)建

    gulp加批處理(.bat)實(shí)現(xiàn)ng多應(yīng)用一鍵自動(dòng)化構(gòu)建

    這篇文章主要給大家介紹了利用gulp加上批處理(.bat)實(shí)現(xiàn)ng多應(yīng)用一鍵自動(dòng)化構(gòu)建的相關(guān)資料,文中介紹的很詳細(xì),需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-02-02
  • 淺談如何通過node.js對(duì)數(shù)據(jù)進(jìn)行MD5加密

    淺談如何通過node.js對(duì)數(shù)據(jù)進(jìn)行MD5加密

    本篇文章將主要針對(duì)于在NODE.JS中如何對(duì)數(shù)據(jù)進(jìn)行MD5加密,MD5是一種常用的哈希算法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-05-05

最新評(píng)論

榆树市| 江都市| 张家口市| 新绛县| 淳化县| 天柱县| 贵南县| 靖边县| 彰化市| 邳州市| 安阳县| 百色市| 长丰县| 江都市| 司法| 万源市| 柳江县| 托克逊县| 东台市| 元阳县| 昌宁县| 清流县| 香格里拉县| 琼海市| 梅河口市| 灵石县| 永新县| 安阳市| 鱼台县| 永春县| 通榆县| 团风县| 嘉祥县| 蕉岭县| 固始县| 蚌埠市| 广丰县| 黑河市| 含山县| 旬邑县| 南昌市|