欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

從零學(xué)習(xí)node.js之文件操作(三)

 更新時(shí)間:2017年02月21日 10:19:28   作者:Wenzi  
這篇文章主要給大家介紹了關(guān)于node.js中對(duì)文件和目錄的操作,我們不一個(gè)個(gè)講每個(gè)api的使用,只是從幾個(gè)例子來(lái)了解下下文件系統(tǒng)。需要的朋友可以參考借鑒,下面來(lái)一起看看吧。

一、文件操作

在文件操作里,主要是有文件讀寫,創(chuàng)建、移動(dòng)文件等。

1.1 讀取文件

讀取文本文件時(shí),如.txt, .js, .json等文件,直接使用readFile就可以獲取文件的內(nèi)容。

// server.js
var fs = require('fs');

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

讀取圖片時(shí),我們是不能直接輸出到控制臺(tái)中的,是需要?jiǎng)?chuàng)建一個(gè)服務(wù)器,然后在瀏覽器上進(jìn)行查看。其實(shí)在上節(jié)中,我們已經(jīng)了解過(guò)顯示圖片的過(guò)程了。

// server.js
var http = require('http'),
 fs = require('fs');

http.createServer(function(request, response){
 // 使用二進(jìn)制方式讀取圖片
 fs.readFile('./img/test.png', 'binary', function(err, file){
  if( err ) throw err;
  // 當(dāng)前數(shù)據(jù)以image/png方式進(jìn)行輸出
  response.writeHead(200, {"Content-Type": "image/png"});
  response.write(file, 'binary');
  response.end();
 });
}).listen(3000);
console.log('server has started...');

打開(kāi)瀏覽器:127.0.0.1:3000,就能看到圖片了。

1.2 寫入文件

將字符串寫入到文件文件中,是非常簡(jiǎn)單的操作,使用writeFile即可搞定:

var fs = require('fs');

var data = '從一開(kāi)始,就選擇了做前端開(kāi)發(fā),因?yàn)橛X(jué)得前端開(kāi)發(fā)更貼近用戶,能夠傾聽(tīng)用戶的聲音,更好玩,更有意思,美的更直觀。我們總是在嘗試最新的技術(shù),嘗試更炫的效果,希望更能優(yōu)化用戶的體驗(yàn)效果!';

fs.writeFile('./test.txt', data, function(err){
 if(err) throw err;
 console.log('寫入數(shù)據(jù)成功...');
});

writeFile方法,在沒(méi)有文件時(shí)會(huì)創(chuàng)建文件并寫入;若文件存在則內(nèi)容被覆蓋。

1.3 創(chuàng)建或文件重命名

根據(jù)writeFile的特性,可以使用writeFile寫入空字符串的方式創(chuàng)建文件。

同時(shí),fs.open也可以創(chuàng)建文件:

// 打開(kāi)模式可以使用 w | w+ | a | a+
// 這些模式在打開(kāi)不存在的文件時(shí),會(huì)創(chuàng)建文件
// fd為一個(gè)整數(shù),表示打開(kāi)文件返回的文件描述符,window中又稱文件句柄
fs.open(Date.now()+'.txt', 'a+', function(err, fd){
 if(err) throw err;
 console.log(fd);
})

在文件系統(tǒng)中,有一個(gè)fs.rename的方法,顧名思義,對(duì)文件(文件夾)進(jìn)行重命名。

fs.rename(oldname, newname, callback(err));

特性:

將oldname文件(目錄)移動(dòng)至newname的路徑下,并重新命名;如果oldname和newname是同一個(gè)路徑,則直接進(jìn)行重命名。

二、文件夾操作

通常對(duì)目錄的操作比較簡(jiǎn)單一些。

2.1 讀取文件夾中的文件和文件夾列表

使用fs.readdir(path, callback)可以獲取path路徑下的文件和目錄列表,而且只能讀取直接目錄下的文件和文件夾,子目錄里的是獲取不到的。

fs.readdir('./', function(err, files){
 if(err) throw err;
 console.log( files );
});

輸出結(jié)果:

[
 'img',
 'msg.txt',
 'node_modules',
 'package.json',
 'server.js',
 'test.js',
 'tmp'
]

node_modulestmp是文件夾,剩下的是文件,而且是獲取不到node_modulestmp里面的數(shù)據(jù)。獲取一個(gè)目錄下所有的文件,后面會(huì)講解,稍等。

2.2 刪除文件夾

使用fs.rmdir(path, callback)可以刪除文件夾,但只能刪除空文件夾,如果當(dāng)前路徑不是文件夾或當(dāng)前文件夾不為空,則刪除失敗;刪除的為空文件夾時(shí),可以刪除成功。

fs.rmdir('./tmp', function(err){
 if(err){
  console.log('刪除文件夾失敗');
  throw err;
 }else{
  console.log('刪除成功');
 }
})

如何刪除不為空的目錄,后面會(huì)講解,稍等。

2.3 獲取文件或文件夾的信息

fs.stat(path, callback)能夠獲取path路徑的信息,比如創(chuàng)建時(shí)間,修改時(shí)間,文件大小,當(dāng)前是否為文件,當(dāng)前是否為文件夾等信息;如果path路徑不存在,則拋出異常。

fs.stat('./test.js', function(err, stats){
 if( err ){
 console.log( '路徑錯(cuò)誤' );
 throw err;
 }
 console.log(stats);
 console.log( 'isfile: '+stats.isFile() ); // 是否為文件
 console.log( 'isdir: '+stats.isDirectory() ); // 是否為文件夾
});

結(jié)果:

{
 dev: -29606086,
 mode: 33206,
 nlink: 1,
 uid: 0,
 gid: 0,
 rdev: 0,
 blksize: undefined,
 ino: 2251799813687343,
 size: 2063, // path路徑為文件夾時(shí),size為0
 blocks: undefined,
 atime: Thu Jan 12 2017 21:12:36 GMT+0800 (中國(guó)標(biāo)準(zhǔn)時(shí)間),
 mtime: Sat Jan 14 2017 21:57:26 GMT+0800 (中國(guó)標(biāo)準(zhǔn)時(shí)間),
 ctime: Sat Jan 14 2017 21:57:26 GMT+0800 (中國(guó)標(biāo)準(zhǔn)時(shí)間),
 birthtime: Thu Jan 12 2017 21:12:36 GMT+0800 (中國(guó)標(biāo)準(zhǔn)時(shí)間)
}
isfile: true // 是否為文件
isdir: false // 是否為文件夾

關(guān)于這幾個(gè)時(shí)間屬性的理解,可以參考這篇文章

stats中的size屬性就是當(dāng)前文件的大?。▎挝唬鹤止?jié),除以1024即為kb),stats還有下面方法可供使用:

  1. stats.isFile()
  2. stats.isDirectory()
  3. stats.isBlockDevice()
  4. stats.isCharacterDevice()
  5. stats.isSymbolicLink() (only valid with fs.lstat())
  6. stats.isFIFO()
  7. stats.isSocket()

fs.stat(path, callback)是異步執(zhí)行的,對(duì)應(yīng)的還有同步執(zhí)行版本:fs.statSync(path) ,這個(gè)方法返回的就是fs.stats實(shí)例。

三、綜合運(yùn)用

我們?cè)谏厦娴闹v解中,還留著兩個(gè)功能沒(méi)實(shí)現(xiàn),這里實(shí)現(xiàn)一下它的過(guò)程。

3.1 遍歷目錄中所有的文件

我們已經(jīng)知道使用readdir只能獲取當(dāng)前目錄里的文件和文件夾名稱,為了獲取這個(gè)目錄里所有的文件名稱,只能是讀取當(dāng)前目錄里所有的文件夾里的文件。這里我們使用遞歸的方法,如果當(dāng)前資源是文件,則進(jìn)行存儲(chǔ),是文件夾則進(jìn)行遞歸進(jìn)一步檢索,直到把所有的文件夾遍歷完畢。

// 獲取文件夾中所有的文件
function readDirAll(path){
 // 獲取字符串的最后一個(gè)字符
 var getLastCode = function(str){
  return str.substr(str.length-1, 1);
 }

 var result = []; // 存儲(chǔ)獲取到的文件
 var stats = fs.statSync(path); // 獲取當(dāng)前文件的狀態(tài)
 if( stats.isFile() ){
  result.push(path);
 }else if( stats.isDirectory() ){
  // 若當(dāng)前路徑是文件夾,則獲取路徑下所有的信息,并循環(huán)
  var files = fs.readdirSync(path);

  for(var i=0, len=files.length; i<len; i++){
   var item = files[i],
    itempath = getLastCode(path)=='/' ? path+item : path+'/'+item; // 拼接路徑
   var st = fs.statSync(itempath);
   if( st.isFile() ){
    result.push(itempath);
   }else if( st.isDirectory() ){
    // 當(dāng)前是文件夾,則遞歸檢索,將遞歸獲取到的文件列表與當(dāng)前result進(jìn)行拼接
    var s = readDirAll( itempath );
    result = result.concat( s );
   }
  }
 }
 return result;
}
console.log( readDirAll('./') );

使用此程序獲取當(dāng)前目錄中所有的文件(展示的為部分文件):

[ 
 './bing.doc',
 './img/1484234634801.png',
 './img/1484234660592.png',
 './img/test.png',
 './inter.js',
 './msg.txt',
 './node_modules/formidable/.npmignore',
 './node_modules/formidable/.travis.yml',
 './node_modules/formidable/index.js',
 './node_modules/formidable/lib/file.js',
 './node_modules/formidable/lib/incoming_form.js',
 './node_modules/formidable/lib/index.js',
 ...
]

如果想要輸出一種樹形的結(jié)構(gòu),就可以對(duì)當(dāng)前的遞歸程序進(jìn)行改造,比如我想要輸出如下的這種結(jié)果,那么,就要分析這種結(jié)構(gòu)的特點(diǎn):

bing.doc         
img           
 |---1484234634801.png     
 |---1484234660592.png     
 |---test.png       
inter.js         
msg.txt          
node_modules        
 |---formidable       
  |---.npmignore      
  |---.travis.yml      
  |---index.js      
  |---lib        
   |---file.js 
   |---incoming_form.js 
   |---index.js

可以看出的規(guī)律:

  1. 第一層級(jí)的文件和文件夾前面是沒(méi)有空格和字符的;
  2. 第一級(jí)子目錄中的文件或文件夾前面是1組空格和1個(gè)字符;
  3. 第二級(jí)子目錄中的文件或文件夾前面是2組空格和1個(gè)字符;
  4. 依次類推…

我們可以再傳遞一個(gè)depth來(lái)表示當(dāng)前目錄的層級(jí),然后計(jì)算出前面空格的數(shù)量:

// depth為遞歸的深度,可根據(jù)遞歸的深度輸出文件名稱前面的格式
function readDirAll(path, depth){
 // 獲取字符串
 var getLastCode = function(str){
  return str.substr(str.length-1, 1);
 }

 depth = depth || 0; // 默認(rèn)為0
 var fir_code = '';

 // 計(jì)算文件名稱前面的字符,4個(gè)空格為1組
 for(var j=0; j<depth; j++){
  fir_code += ' ';
 }
 depth && (fir_code += '|---');

 var stats = fs.statSync(path);
 if( stats.isFile() ){
  console.log( fir_code+path );
 }else if( stats.isDirectory() ){
  var files = fs.readdirSync(path);
  for(var i=0, len=files.length; i<len; i++){
   var item = files[i],
    itempath = getLastCode(path)=='/' ? path+item : path+'/'+item,
    st = fs.statSync(itempath);

   console.log( fir_code+item );
   if( st.isDirectory() ){
    var s = readDirAll( itempath, depth+1 );
   }
  }
 }
}
console.log( readDirAll('./') ); 

3.2 刪除目錄

使用fs.rmdir(path)是有局限性的,只能刪除空目錄,如果是個(gè)非空目錄,我們可以根據(jù)上面的思路,寫出一個(gè)能刪除當(dāng)前目錄下所有的文件。遞歸,只要找到里面的文件夾就遞歸尋找,直到找到最底層,把最底層的文件刪除,然后再逐級(jí)向上刪除文件夾,直到刪除到當(dāng)前目錄。

// 刪除path下所有的文件和文件夾,包括path自己
function rmDirAll(path){
 // 獲取字符串
 var getLastCode = function(str){
  return str.substr(str.length-1, 1);
 }

 var stats = fs.statSync(path); // 獲取當(dāng)前文件的狀態(tài)
 if( stats.isFile() ){
  fs.unlinkSync(path);
  console.log( '刪除成功: '+path );
 }else if( stats.isDirectory() ){
  // 若當(dāng)前路徑是文件夾,則獲取路徑下所有的信息,并循環(huán)
  var files = fs.readdirSync(path);

  for(var i=0, len=files.length; i<len; i++){
   var item = files[i],
    itempath = getLastCode(path)=='/' ? path+item : path+'/'+item; // 拼接路徑
   var st = fs.statSync(itempath);
   if( st.isFile() ){
    fs.unlinkSync(itempath);
    console.log( '刪除成功: '+itempath );
   }else if( st.isDirectory() ){
    // 當(dāng)前是文件夾,則遞歸檢索
    rmDirAll( itempath );
   }
  }
  // 現(xiàn)在可以刪除文件夾
  fs.rmdir(path);
  console.log( '刪除成功: '+path );
 }
}
rmDirAll('./img'); 

則刪除時(shí)輸出的信息如下,先把內(nèi)部的文件和文件夾刪除干凈,最后刪除 ‘./img':

刪除成功: ./img/1484234634801.png
刪除成功: ./img/1484234660592.png
刪除成功: ./img/gggg/est.txt
刪除成功: ./img/gggg
刪除成功: ./img/test.png
刪除成功: ./img

當(dāng)然,你也可以試著實(shí)現(xiàn)這樣的程序:

  1. 刪除path內(nèi)部所有的內(nèi)容,同時(shí)能保留下path目錄
  2. 只刪除文件,將所有的空文件夾保留下來(lái)
  3. 將內(nèi)部所有的文件都移動(dòng)到path的根目錄下,并刪除空文件夾

等等,都可以試著實(shí)現(xiàn)一下。

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,其實(shí)文件系統(tǒng)里也有很多的內(nèi)容需要學(xué)習(xí),這里只是拋磚引玉,希望通過(guò)自己一點(diǎn)的微薄知識(shí),能為大家指點(diǎn)迷津。小編還會(huì)繼續(xù)分享關(guān)于node入門學(xué)習(xí)的文章,感興趣的朋友們請(qǐng)繼續(xù)關(guān)注腳本之家。

相關(guān)文章

最新評(píng)論