node學(xué)習(xí)一 (node模塊化,fs常見文件操作)

node中的模塊: commonJs

模塊是Node.js 應(yīng)用程序的基本組成部分,文件和模塊是一一對(duì)應(yīng)的。換言之,一個(gè) Node.js 文件就是一個(gè)模塊,這個(gè)文件可能是JavaScript 代碼、JSON 或者編譯過的C/C++ 擴(kuò)展。

  • 一個(gè)文件就是一個(gè)模塊
    采用module.exports 暴露方法和屬性
    通過require外部可以導(dǎo)入

每個(gè)模塊內(nèi)部,module變量代表當(dāng)前模塊。這個(gè)變量是一個(gè)對(duì)象,它的exports屬性(即module.exports)是對(duì)外的接口。加載某個(gè)模塊,其實(shí)是加載該模塊的module.exports屬性。

var x = 5;
var addX = function (value) {
  return value + x;
};
module.exports.x = x;
module.exports.addX = addX;

上面代碼通過module.exports輸出變量x和函數(shù)addX。
require方法用于加載模塊。

var example = require('./example.js');  
//相當(dāng)于 example = module.exports
console.log(example.x); // 5
console.log(example.addX(1)); // 6

node中的模塊和es6中的模塊有一定的區(qū)別,本文不做比較,這里我們后面再做了解。因?yàn)楝F(xiàn)在nodejs 不支持es6語法,所有在webpack 的配置文件里面還要通過require來導(dǎo)入。

包的入口文件index.js

在組成一個(gè)包的所有子模塊中,需要有一個(gè)入口模塊,入口模塊的導(dǎo)出對(duì)象被作為包的導(dǎo)出對(duì)象。例如有以下目錄結(jié)構(gòu)。

- /home/user/lib/
    - cat/
        head.js
        body.js
        main.js

使用require('/home/user/lib/cat/main')能達(dá)到目的,但是入口模塊名稱出現(xiàn)在路徑里看上去不是個(gè)好主意。

當(dāng)模塊的文件名是index.js,加載模塊時(shí)可以使用模塊所在目錄的路徑代替模塊文件路徑,因此以下兩條語句等價(jià)。

var cat = require('/home/user/lib/cat');
var cat = require('/home/user/lib/cat/index');

這樣處理后,就只需要把包目錄路徑傳遞給require函數(shù),感覺上整個(gè)目錄被當(dāng)作單個(gè)模塊使用,更有整體感。

package.json

如果想自定義入口模塊的文件名和存放位置,就需要在包目錄下包含一個(gè)package.json文件,并在其中指定入口模塊的路徑。上例中的cat模塊可以重構(gòu)如下。

- /home/user/lib/
    - cat/
        + doc/
        - lib/
            head.js
            body.js
            main.js
        + tests/
        package.json

其中package.json內(nèi)容如下。
{
"name": "cat",
"main": "./lib/main.js"
}

如此一來,就同樣可以使用require('/home/user/lib/cat')的方式加載模塊。NodeJS會(huì)根據(jù)包目錄下的package.json找到入口模塊所在位置。 這樣他就不會(huì)默認(rèn)去找cat文件夾下的index文件了,而是通過package.json來找入口文件。

內(nèi)置FS模塊

Node.js 提供一組類似 UNIX(POSIX)標(biāo)準(zhǔn)的文件操作API。 Node 導(dǎo)入文件系統(tǒng)模塊(fs)語法如下所示:

const fs = require("fs")

異步和同步

Node.js 文件系統(tǒng)(fs 模塊)模塊中的方法均有異步和同步版本,例如讀取文件內(nèi)容的函數(shù)有異步的 fs.readFile() 和同步的 fs.readFileSync()。

異步的方法函數(shù)最后一個(gè)參數(shù)為回調(diào)函數(shù),回調(diào)函數(shù)的第一個(gè)參數(shù)包含了錯(cuò)誤信息(error)。

建議大家使用異步方法,比起同步,異步方法性能更高,速度更快,而且沒有阻塞。

fs常用方法

這里介紹練習(xí)的方法都是異步的方法,同步方法使用這里不做介紹

  • fs.stat
    檢測(cè)傳入的路徑是文件還是目錄
fs.stat('./html',function(err,data){
    if(err){
        console.log(err);
        return;
    }
    console.log(`是文件嗎:${data.isFile()}`);
    console.log(`是目錄嗎: ${data.isDirectory()}`);
})
fs.stat('./html/app.html',function(err,data){
    if(err){
        console.log(err);
        return;
    }
    console.log(`是文件嗎:${data.isFile()}`);
    console.log(`是目錄嗎:${data.isDirectory()}`);
})
  • fs.mkdir
    創(chuàng)建目錄
    path 將創(chuàng)建的目錄路徑
    mode 目錄權(quán)限(讀寫權(quán)限),默認(rèn)777
    callback 回調(diào),傳遞異常參數(shù)err
    如果目錄不存在 就創(chuàng)建, 如果存在 就報(bào)錯(cuò) 改路徑已經(jīng)存在
fs.mkdir(`./css`,function(err,data){
    if(err){
        console.log(err);
        return;
    }
    console.log('創(chuàng)建成功');
})
  • fs.writeFile
    創(chuàng)建寫入文件
    如果文件不存在就創(chuàng)建 如果文件存在 就替換
fs.writeFile('./html/app.html','你好 nodeJs', (err) => {
    if(err){
        console.log(err);
        return;
    }
    console.log('創(chuàng)建寫入文件成功');
})
  • fs.appendFile
    如果文件不存在就創(chuàng)建然后寫入 如果存在就在內(nèi)容后面追加
fs.appendFile('./css/base.css','body{color:red}',(err)=>{
    if(err){
        console.log(err);
        return;
    }
    console.log('appendFile 成功')
})

fs.appendFile('./css/base.css','h2{font-size:12px}',(err)=>{
    if(err){
        console.log(err);
        return;
    }
    console.log('appendFild 成功');
})
  • fs.readDir
    查看目錄
    會(huì)列出該路徑下的文件和文件夾(只包含兒子,不包含孫子)
 fs.readdir('./html',(err,data)=> {
    if(err){
        console.log(err);
        return;
    }
    console.log(data);
 })
  • fs.rename
    功能:
    1、 重命名文件 2、移動(dòng)文件(相當(dāng)于重命名路徑)
fs.rename('./html/app.html','./html/index.html',(err) => {
    if(err){
        console.log(err);
        return;
    }
    console.log('重命名成功');
})
fs.rename('./css/base.css','./html/index.css',err =>{
    if(err){
        console.log(err);
        return;
    }
    console.log('移動(dòng)成功');
})
  • fs.rmdir
    刪除目錄 但是只能刪除空的目錄
fs.rmdir('./html/html2/',err => {
    if(err){
        console.log(err);
        return;
    }
    console.log('刪除目錄成功');
})
  • fs.unlink
    刪除文件
fs.unlink('./html/html2/index.html',err => {
    if(err){
        console.log(err);
        return;
    }
    console.log('刪除文件成功');
})

文件流

閱讀流


// 創(chuàng)建一個(gè)只讀的流
const createRead = fs.createReadStream('./data/input.txt');

let count = 0;
let str = '';

// 當(dāng)有數(shù)據(jù)可讀時(shí)觸發(fā)
createRead.on('data',(data)=>{
    str=str+data;
    count++;
})

// 當(dāng)沒有更多的數(shù)據(jù)可讀時(shí)觸發(fā)
createRead.on('end',()=> {
    console.log(str);
    console.log(count)
})
// 發(fā)生錯(cuò)誤事觸發(fā)
createRead.on('err',(err)=>{
    console.log(err.stack);
})

寫入的流

// 寫入的流
const fs = require('fs');

const data = '測(cè)試測(cè)試測(cè)試測(cè)試測(cè)試測(cè)試測(cè)試測(cè)試測(cè)試測(cè)試測(cè)試測(cè)試測(cè)試測(cè)試';

let str='';

// 創(chuàng)建一個(gè)寫入的流 并寫入到 ./data/data.txt文件中
const writeStream = fs.createWriteStream('./data/data.txt');

for(var i=0;i<500;i++){
    str = str + `${data}${i}\r\n`;
}

// 寫入data數(shù)據(jù) 并設(shè)置格式
writeStream.write(str,'UTF8');

writeStream.end();//如果不寫 end   不會(huì)觸發(fā)finish事件

writeStream.on('finish',()=>{
    console.log('寫入完成');
})

writeStream.on('err',(err)=>{
    console.log(err.stack);
})

參考文章:

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容