node寫入文件

最近有個(gè)需求,需要把爬下來的數(shù)據(jù)寫入到文件中纸巷,于是乎查了下相關(guān)的博客和文檔镇草,大概記錄一下,方便以后自己用瘤旨,這個(gè)基本上都是復(fù)制粘貼來的梯啤,主要是方便自己用,其他人看到了覺得有用就用存哲,沒用也可以吐槽因宇,就是抄的反正。
Nodejs文件覆蓋祟偷、追加察滑、讀取、全量復(fù)制

同步版 從這里復(fù)制的

邏輯處理類的實(shí)現(xiàn):syncdata.js

const fs = require("fs");
 
/**
 * update file
 * @param   res  to update content
 * @returns update operation result
 */
async function updateResFile (res) {
    return new Promise((resolve, reject) => {
        fs.writeFile(`${conf['workdir']}${conf['res']}`, res, (err) => {
            if (err) {
                console.error(`error happened when updateResFile inner: ${err.message}`);
                reject(false);
                return;
            } else {
                resolve(true);
                return;
            }
          });
    }).catch(error => {
        console.error(`error happened when updateResFile: ${error.message}`);
        return false;
    });
}
 
/**
 * break line append log
 * @param log log content
 * @returns append operation result
 */
async function appendFile (log) {
    return new Promise((resolve, reject) => {
        if ("windows" == conf['os']) {
            log+='\r\n';
        } else {
            log+='\n';
        }
        fs.appendFile(`${conf['workdir']}${conf['log']}`, log, (err) => {
            if (err) {
                console.error(`error happened when appendFile inner: ${err.message}`);
                reject(false);
                return;
            } else {
                resolve(true);
                return;
            }
          });
    }).catch(error => {
        console.error(`error happened when appendFile: ${error.message}`);
    });
}
 
/**
 * execute copy file logic
 * @param {*} src 
 * @param {*} dst 
 * @param {*} callback 
 */
async function handleDir (src, dst) {
    return new Promise(async (resolve, reject) => {
        fs.access(dst, fs.constants.F_OK, async (err) => {
            if (err) {
                fs.mkdir(dst, { recursive: true }, async (err) => {
                    if (err) {
                        console.error(`error happened when handleDir.mkdir: ${err.message}`);
                        reject(`error happened when handleDir.mkdir: ${err.message}`);
                        return;
                    } else {
                        await copyDir(src, dst);
                    }
                  });
                
            } else {
                await copyDir(src, dst);
            }
            resolve(true);
        });
    }).catch(error => {
        console.error(`error happened when handleDir: ${error.message}`);
    });
}
 
/**
 * execute iterator copy directory
 * @param src directory source path
 * @param dst directory destination path
 * @returns copy result
 */
async function copyDir (src, dst) {
    return new Promise(async (resolve, reject) => {
        fs.readdir(src, (err, paths) => {
            paths.forEach(function(path){
              var _src=src+'/'+path;
              var _dst=dst+'/'+path;
              fs.stat(_src, async function(err,stats){
                if(err) {
                    console.error(`copyDir failed, caused by ${JSON.stringify(err)}`);
                    reject(false);
                } else if(stats.isFile()){
                  let readable=fs.createReadStream(_src);
                  let writable=fs.createWriteStream(_dst);
                  readable.pipe(writable);
                  readable.on('end', () => {
                    resolve(true);
                  });
                }else if(stats.isDirectory()){
                  await handleDir(_src, _dst, copyDir);
                }
              });
            });
        });
    }).catch(error => {
        console.error(`error happened when copyDir: ${error.message}`);
    });
}
 
/**
 * read file sync
 * @param path filefullpath
 * @returns file content
 */
async function readFile (path) {
    return new Promise((resolve, reject) => {
        fs.readFile(path, conf['encode'] , (err, data) => {
            if (err) {
                console.error(`readFile failed, caused by ${JSON.stringify(err)}`);
                reject(false);
            } else {
                resolve(data);
                return;
            }
          });
    }).catch(error => {
        console.error(`error happened when readFile: ${error.message}`);
    });
}
 
/**
 * main entrance
 */
async function syncFile () {
 
    console.log(`begin ------- ${new Date().getTime()}`);
    let cpRes = await copyDir('D:/開發(fā)文檔/郵件文檔/1-郵件附件', './2');
    console.log(`result is ${cpRes}`);
    console.log(`end ------- ${new Date().getTime()}`);
}
 
// call
syncFile ();

同一目錄下的配置文件conf.json

{
    "os" : "windows",
    "encode" : "utf-8",
    "workdir" : "/home/",
    "latestVersion" : "latestVersion.txt",
    "currentVersion" : "currentVersion.txt",
    "log" : "log.txt",
    "res" : "syncResult.txt",
    "copySrc" : "/copySrc/",
    "copyDst" : "/copyDst/",
    "success-text" : "success",
    "fail-text" : "fail",
    "dateformat" : "YYYY-MM-DD"
}

執(zhí)行方式:
cd到syncdata.js同一級(jí)目錄修肠,執(zhí)行node syncdata.js

異步版 從這里復(fù)制的

所有方法都是異步的贺辰,如果需要同步則需要修改fs的方法,并使用Promise進(jìn)行包裝嵌施,另外需要注意饲化,全部復(fù)制的方法需要傳入兩個(gè)目錄,不帶文件的path吗伤,并且是有最大文件打開數(shù)量限制的吃靠,如果是大文件但文件數(shù)量較少則適合使用,如果是小文件且數(shù)量大足淆,則不適合巢块,建議進(jìn)行先打成壓縮包礁阁,再進(jìn)行傳輸。

邏輯處理類的實(shí)現(xiàn):syncdata.js

const fs = require("fs");
 
// local path
const conf = require("./conf.json");
 
/**
 * update file
 * @param   res  to update content
 * @returns update operation result
 */
function updateResFile (res) {
    return fs.writeFileSync(`${conf['workdir']}${conf['res']}`, res);
}
 
/**
 * break line append log
 * @param log log content
 * @returns append operation result
 */
function appendFile (log) {
    if ("windows" == conf['os']) {
        log+='\r\n';
    } else {
        log+='\n';
    }
    return fs.appendFileSync(`${conf['workdir']}${conf['log']}`, log);
}
 
/**
 * handle directory
 * @param {*} src 
 * @param {*} dst 
 * @param {*} callback 
 */
function handleDir(src, dst) {
    fs.access(dst, fs.constants.F_OK, (err) => {
        if (err) {
            fs.mkdirSync(dst);
            copyDir(src, dst);
        } else {
            copyDir(src, dst);
        }
    });
}
 
/**
 * execute iterator copy directory
 * @param src directory source path
 * @param dst directory destination path
 * @returns copy result
 */
function copyDir (src, dst) {
    // read file path sync
    let paths = fs.readdirSync(src);
    paths.forEach(function(path){
      var _src=src+'/'+path;
      var _dst=dst+'/'+path;
      
      //stats object, include its own attribute
      fs.stat(_src,function(err,stats){
        if(err) {
            console.log(`copyDir failed, caused by ${JSON.stringify(err)}`);
            return false;
        } else if(stats.isFile()){
          let readable=fs.createReadStream(_src);
          let writable=fs.createWriteStream(_dst);
          readable.pipe(writable);
        }else if(stats.isDirectory()){
          handleDir(_src, _dst, copyDir);
        }
      });
    });
    return true;
}
 
/**
 * read file sync
 * @param path filefullpath
 * @returns file content
 */
function readFile (path) {
    return fs.readFileSync(path, conf['encode']);
}
 
/**
 * main entrance
 */
function syncFile () {
    // test code here
}
 
// call
syncFile ();
同一目錄下的配置文件`conf.json`
```json
{
    "os" : "windows",
    "encode" : "utf-8",
    "workdir" : "/home/",
    "latestVersion" : "latestVersion.txt",
    "currentVersion" : "currentVersion.txt",
    "log" : "log.txt",
    "res" : "syncResult.txt",
    "copySrc" : "/copySrc/",
    "copyDst" : "/copyDst/",
    "success-text" : "success",
    "fail-text" : "fail",
    "dateformat" : "YYYY-MM-DD"
}

執(zhí)行方式:
cd到syncdata.js同一級(jí)目錄夕冲,執(zhí)行node syncdata.js

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末氮兵,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子歹鱼,更是在濱河造成了極大的恐慌泣栈,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,000評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件弥姻,死亡現(xiàn)場(chǎng)離奇詭異南片,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)庭敦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,745評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門疼进,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人秧廉,你說我怎么就攤上這事伞广。” “怎么了疼电?”我有些...
    開封第一講書人閱讀 168,561評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵嚼锄,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我蔽豺,道長(zhǎng)区丑,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,782評(píng)論 1 298
  • 正文 為了忘掉前任修陡,我火速辦了婚禮沧侥,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘魄鸦。我一直安慰自己宴杀,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,798評(píng)論 6 397
  • 文/花漫 我一把揭開白布号杏。 她就那樣靜靜地躺著婴氮,像睡著了一般。 火紅的嫁衣襯著肌膚如雪盾致。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,394評(píng)論 1 310
  • 那天荣暮,我揣著相機(jī)與錄音庭惜,去河邊找鬼。 笑死穗酥,一個(gè)胖子當(dāng)著我的面吹牛护赊,可吹牛的內(nèi)容都是我干的惠遏。 我是一名探鬼主播,決...
    沈念sama閱讀 40,952評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼骏啰,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼节吮!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起判耕,我...
    開封第一講書人閱讀 39,852評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤透绩,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后壁熄,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體帚豪,經(jīng)...
    沈念sama閱讀 46,409評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,483評(píng)論 3 341
  • 正文 我和宋清朗相戀三年草丧,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了狸臣。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,615評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡昌执,死狀恐怖烛亦,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情懂拾,我是刑警寧澤煤禽,帶...
    沈念sama閱讀 36,303評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站委粉,受9級(jí)特大地震影響呜师,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜贾节,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,979評(píng)論 3 334
  • 文/蒙蒙 一汁汗、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧栗涂,春花似錦知牌、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,470評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至忿墅,卻和暖如春扁藕,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背疚脐。 一陣腳步聲響...
    開封第一講書人閱讀 33,571評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工亿柑, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人棍弄。 一個(gè)月前我還...
    沈念sama閱讀 49,041評(píng)論 3 377
  • 正文 我出身青樓望薄,卻偏偏與公主長(zhǎng)得像疟游,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子痕支,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,630評(píng)論 2 359