nodejs遍歷文件夾下並操做HTML/CSS/JS/PNG/JPG

需求描述,因爲工做的須要,須要將本來用於1280 720的網頁改成1920 1080的網頁(電視端頁面)。需求能夠拆分爲兩部分,代碼部分的修改以及圖片的修改。在代碼部分,須要將全部位置以及大小相關的值乘以1.5,圖片的尺寸也要放大1.5倍。
首先使用nodejs遍歷當前的文件夾:css

// 遍歷全部的文件
var fs = require("fs")
var path = require("path")
var relativePath = '\\test'
// 拿到須要遍歷的路徑
var root = path.join(__dirname)+relativePath

readDirSync(root)
// 使用異步獲取路徑
// 參數是遍歷文件的根路徑
function readDirSync(path){
    var pa = fs.readdirSync(path);
    // 循環遍歷當前的文件以及文件夾
    pa.forEach(function(ele,index){
        var info = fs.statSync(path+"\\"+ele)    
        if(info.isDirectory()){
            // console.log("dir: "+ele)
            readDirSync(path+"\\"+ele);
        }else{
            var filePath = path +'\\'+ ele;
            // 找到 .css .html .js 文件
            let fileNameReg = /\.css|\.js|\.html|\.htm/g;
            let shouldFormat =  fileNameReg.test(filePath);
            if (shouldFormat) {
                console.log('find  file:',filePath);
                // 這裏就拿到了符合條件的文件路徑,後面就能夠根據這個路徑來執行相關的操做
            }
        }    
    })
}

若是是HTMLCSSJS文件使用nodejs文件相關api來操做文件,首先是讀取到文件,而後是寫入文件。代碼:html

var formatObj = new ChangePosFor4K();// 建立對象,構造函數在下文尾部

function readFile(params) {
    // 讀取文件示例
    fs.readFile(params, function (err, data) {
        if (err) {
            console.log('happen an error when read file , error is ' + err)
        }
        else {
            var codeTxt = data.toString();
            // 使用對象來修改文件內容,執行位置以及大小相關值的擴大操做
            var formatReturn = formatObj.formatNumber(codeTxt);
            codeTxt = formatReturn.code;
            // 給不一樣的文件添加不一樣的註釋
            let jsFileReg = /.js$/i;
            let htmlFileReg = /.html$|.htm$/i;
            let cssFileReg = /.css$/i;
            let tip1 = 'auto formatting tool has check this file.'
            let tip2 = '  block has been handle in this code.'
            let now = new Date();
            if ( jsFileReg.test(params) || cssFileReg.test(params) ) {
                codeTxt += '\n /* '+ tip1 +'*/'
                codeTxt +=  '\n /* '+ formatReturn.times +' '+ tip2+' at ' + now +'*/'
            } else if(htmlFileReg.test(params)){
                codeTxt += '\n <!-- '+ tip1 +' -->'
                codeTxt +=  '\n <!-- '+ formatReturn.times +' '+ tip2+' at ' + now +'-->'
            }
            // 將修改好內容寫入當前路徑的文件
            writeFile(params,codeTxt);
        }
    })   
}


// 寫入文件
// fs.writeFile(file, data[, options], callback)
// file - 文件名或文件描述符。
// data - 要寫入文件的數據,能夠是 String(字符串) 或 Buffer(流) 對象。
// options - 該參數是一個對象,包含 { encoding, mode, flag } 。默認編碼爲 utf8, 模式爲 0666 , flag 爲 'w'
// callback - 回調函數,回調函數只包含錯誤信息參數(err) ,在寫入失敗時返回。
function writeFile(_path , _txt) {
    fs.writeFile(_path , _txt , function (err) {
        if (err) {
            console.log('happen an error when write file , error is ' + err)
        }
        else{
            console.log("format file success :",_path);
        }
    })
}


// 樣式操做相關
/* 
* fun:
*/
function ChangePosFor4K(){
            
    var format = /\d+px/gi;
    var tempSufixx = '@@' // 臨時佔位符,由於須要靠數字+px的正則來匹配,已經修改過的就不能再有px
    this.formatNumber = function(arg){
        // 匹配出全部的 數字和px的組合 dd.px 
        var initalStr = arg;
        var locIndex = initalStr.search(format); //獲取到起始索引
        var changeTimes = 0;

        while(locIndex>0){
            // 拿到值
            var locStr = getFullPos(initalStr , locIndex);
            // 乘以相關比例
            var locValue =Math.ceil(parseInt(locStr) * 1.5); 
            var locReplaceStr = locValue+tempSufixx;
            // 替換
            initalStr = replaceStr(initalStr , locIndex , locStr.length , locReplaceStr);
            locIndex = initalStr.search(format);
            // 計數
            changeTimes++;
        }
        var locReg = new RegExp(tempSufixx,'gi')
        initalStr = initalStr.replace(locReg , 'px');
        return {code:initalStr,times:changeTimes};
    }
    
    // 根據字符串和起始位置找到 xxx.px 字符串
    function getFullPos(_str , _begin){
        var output = '';
        while(output.indexOf('px')<0){// 當沒有沒有找到完整的字符串
            output += _str.charAt(_begin);
            _begin++;
        }
        return output;
    }

    // 被替換的元素,根據起始索引,替換長度,替換元素 
    function replaceStr( _str , _begin , _len ,  _subStr ){
        // 首先將字符串和拼接字符串轉化爲數組
        var strArr = _str.split('');
        var subStrArr = _subStr;
        // 完成替換
        strArr.splice(_begin,_len,subStrArr);
        return strArr.join('');
    }
}

至此代碼相關操做就已經結束了,下面來圖片操做。這裏的圖片操做藉助了gm,首先經過npm安裝gm,並安裝ImageMagick或者GraphicsMagick軟件。代碼:node

var fs = require('fs');
// 兩個圖片操做底層程序能夠選擇
var gm = require('gm').subClass({ImageMagick: true});
var path = require("path")

var relativePath = '\\test'
var root = path.join(__dirname)+relativePath
// 放大圖片並製做副本
function magnifyImg(_path){
    // 獲取當前圖片的長和寬
    // 將長和寬放大1.5倍
    // 設置新的圖片大小
    // 沒有直接調用magnify,由於magnify不支持小數
    gm(_path)
    .size(function (err , size){
        if (!err){
            // console.log(size.width > size.height ? 'wider' : 'taller than you');
            let nowWidth =parseInt(size.width) ;
            let nowHeight = parseInt(size.height) ;
            let magnifyWidth = Math.floor( nowWidth * 1.5);
            let magnifyHeight = Math.floor( nowHeight * 1.5);
            gm(_path).resizeExact(magnifyWidth,magnifyHeight).write(_path,function(err){
                if (!err) 
                    console.log(_path+'done');
                else
                    console.log(_path+'fail'+err);
            })
            
        }
        else{
            console.log('get size has error '+_path + ' and err is : '+err);
        }
    })
}

至此,功能就完成了。正則表達式

比較有感觸的是在操做代碼中相關位置以及大小的實現過程,碰到了一些困難,開始的時候不知道如何去找到文件中全部符合條件的字符,另外不知道如何替換找到的字符,平時用的都是字符串replace方法,可是replace方法會替換掉全部的符條件的地方。後來根據索引和長度來實現定位和替換。圖片的操做就是百度以後根據別人寫的來作的,藉助ImageMagic工具仍是能實現很是豐富的功能,具體的可見gm的GitHub。可是放大的api不能支持小數位的放大,須要多走一步,首先獲取當前大小,而後再設置大小。一樣在圖片的放大過程當中,會發生拉伸變模糊的問題,若是對圖片的質量有較高要求的話,最後仍是經過美工來作。可以彌補下美工缺少的問題。npm

猜到的坑是replace方法,replace方法是不會改變原字符串的。api

此次可以順利完成主要得益於正則表達式,學好正則表達式對於數據的處理仍是很是重要的。後面再對正則表達式總結學習一下,以此完成知識的輸出。數組

相關文章
相關標籤/搜索