zoukankan      html  css  js  c++  java
  • nodejs遍历文件夹下并操作HTML/CSS/JS/PNG/JPG

    需求描述,由于工作的需要,需要将原本用于1280 720的网页改为1920 1080的网页(电视端页面)。需求可以拆分为两部分,代码部分的修改以及图片的修改。在代码部分,需要将所有位置以及大小相关的值乘以1.5,图片的尺寸也要放大1.5倍。
    首先使用nodejs遍历当前的文件夹:

    
    // 遍历所有的文件
    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来操作文件,首先是读取到文件,然后是写入文件。代码:

    
    
    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 += '
     /* '+ tip1 +'*/'
                    codeTxt +=  '
     /* '+ formatReturn.times +' '+ tip2+' at ' + now +'*/'
                } else if(htmlFileReg.test(params)){
                    codeTxt += '
     <!-- '+ tip1 +' -->'
                    codeTxt +=  '
     <!-- '+ 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软件。代码:

    
    
    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不能支持小数位的放大,需要多走一步,首先获取当前大小,然后再设置大小。同样在图片的放大过程中,会发生拉伸变模糊的问题,如果对图片的质量有较高要求的话,最后还是通过美工来做。能够弥补下美工缺乏的问题。

    猜到的坑是replace方法,replace方法是不会改变原字符串的。

    这次能够顺利完成主要得益于正则表达式,学好正则表达式对于数据的处理还是非常重要的。后面再对正则表达式总结学习一下,以此完成知识的输出。

    来源:https://segmentfault.com/a/1190000016868498

  • 相关阅读:
    shell getopt getopts获取参数
    apache+svn+ladp认证
    SVN 迁移项目分支
    iptables 优先级
    很实用的一篇HTTP状态码
    套路还在——矩阵计算估值
    CU上看到的一个简单的算法帖子
    linux下服务端实现公网数据转发
    c++接口实现与分离(转载)
    c++继承概念
  • 原文地址:https://www.cnblogs.com/datiangou/p/10164305.html
Copyright © 2011-2022 走看看