Node fs.writeFileSync 操作中 UTF-8 格式 BOM 缺失

NodeJS 默認使用 utf8 格式,這點是沒錯的

瞎逼逼一下,不解釋,意會就好:

  • 萬花叢中過,片葉不沾身
  • 常在江邊走,哪有不濕鞋
o.gif

<br />


故事由來

后端給我的是 .cshtml 文件,代碼粘貼來復制去太惡心了,于是我寫了一段腳本:

const ORIGIN_DIR = './origin'; // 源目錄
const DESTINATION_DIR = './destination';

let fs = require('fs');

//  遍歷目錄得到文件信息
function walk(path, callback) {
    let files = fs.readdirSync(path);

    files.forEach(function(file){
        if (fs.statSync(path + '/' + file).isFile()) {
            callback(path, file);
        }
    });
}

function setUp () {
    if ( !fs.existsSync(DESTINATION_DIR) ) {
        fs.mkdirSync(DESTINATION_DIR);
    }

    // 運行
    walk(ORIGIN_DIR, function (path, file) {
        let fileName = file.match(/(\S+)(\.\S+)$/)[1]; // 獲得文件名

        let oldPath = path + '/' + file, // 原路徑
            newPath = DESTINATION_DIR + '/' + fileName + '.cshtml'; // 新路徑

        let html = fs.readFileSync(oldPath);

        fs.writeFileSync(newPath, html);
    });
}

setUp();

然后我扔到后端服務器,中文就亂碼了,不開玩笑,哥是認真的。

gibberish.png

<br />


懵逼中

我就納悶了,文件明明是 UTF-8,為什么就亂碼了?~ o( ̄ ̄)o
拿后端的文件,粘代碼進去,WTF,居然正常,這不科學 = =

2.0 視力的我發(fā)現兩個文件字節(jié)大小不一樣,嗯哼......

怎么看出來的?你猜

使用 Beyond Compare 軟件對比一下:

missBOM.png

字節(jié)順序標記(ByteOrderMark),好陌生的名詞,茫然、懵逼。

<br />


墻里開花墻外香

縱你搜它上百度,驀然回首,那人卻在,燈火闌珊處。嗯,好詩,好詩,此處應該有掌聲 ( ̄ ̄)"
chrome 定位到 StackOverflow ,好,找到解決方法:

// UTF-8 doesn't require a bom, but you can add it by yourself of course.
filesys.writeFile('test.txt', '\ufeffThis is an example with accents : é è à ','utf8', function (err) {});

原來開頭加 \uFEFF 就好了...大端,不覺明厲

<br />


測試

修改后腳本(就是加了一行):

const ORIGIN_DIR = './origin'; // 源目錄
const DESTINATION_DIR = './destination';

let fs = require('fs');

//  遍歷目錄得到文件信息
function walk(path, callback) {
    let files = fs.readdirSync(path);

    files.forEach(function(file){
        if (fs.statSync(path + '/' + file).isFile()) {
            callback(path, file);
        }
    });
}

function setUp () {
    if ( !fs.existsSync(DESTINATION_DIR) ) {
        fs.mkdirSync(DESTINATION_DIR);
    }

    // 運行
    walk(ORIGIN_DIR, function (path, file) {
        let fileName = file.match(/(\S+)(\.\S+)$/)[1]; // 獲得文件名

        let oldPath = path + '/' + file, // 原路徑
            newPath = DESTINATION_DIR + '/' + fileName + '.cshtml'; // 新路徑

        let html = '\uFEFF'; // BOM

        html += fs.readFileSync(oldPath);
        fs.writeFileSync(newPath, html);
    });
}

setUp();

再虐一次,你是否會有感覺:

withBOM.png

O yeah ! 完美對稱~

上傳,上傳,上傳測試:

normal.png

Done !

<br />


總結

  • writeFileSyncwriteFile 都會有這個問題,其實之前合并 markdown 文件我就碰見過...
  • 不會就搜索,沒啥不好 ~

—— 2017/02/16 By Live


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

相關閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,048評論 25 709
  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現,斷路器,智...
    卡卡羅2017閱讀 136,564評論 19 139
  • 你向閨蜜抱怨老公每天回家不陪你,只顧自己玩手機時,閨蜜說“這算不了什么。好歹你們每天能見到他。我家老公是每年在酒店...
    弗蘭克閱讀 11,299評論 30 274
  • 1.感恩我有一對負責任的父母,將我養(yǎng)大并供我上大學,教會我說第一句話,教會我走第一步路,教會我穿衣服。 2.感恩我...
    空空dj閱讀 206評論 0 0
  • 文/筱安時光 1 窗外雨絲飄飄涼意直撲面 窗內思念如潮盡把我淹 我抱著腿蜷縮在床邊 2 初秋的天氣 若打噴嚏 那是...
    筱安時光閱讀 372評論 3 8

友情鏈接更多精彩內容