需求描述,由于工作的需要,需要将原本用于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 += '\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软件。代码:



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

nodejs遍历文件夹下并操作HTML/CSS/JS/PNG/JPG的更多相关文章

  1. nodejs 遍历文件夹下所有的图片改名为中文

    安装依赖 $ npm init -y && npm i fs-extra globby request -S main.js const fs = require('node-fs-e ...

  2. Java遍历文件夹下的所以文件

    利用Java递归遍历文件夹下的所以文件,然后对文件进行其他的操作.如:对文件进行重命名,对某一类文件进行重编码.可以对某一工程下的全部.java文件进行转码成utf-8等 代码如下,这里只对文件进行重 ...

  3. C#遍历文件夹下所有文件

    FolderForm.cs的代码如下: using System; using System.Collections.Generic; using System.Diagnostics; using ...

  4. JAVA 遍历文件夹下的所有文件

    JAVA 遍历文件夹下的所有文件(递归调用和非递归调用) 1.不使用递归的方法调用. public void traverseFolder1(String path) { int fileNum = ...

  5. PHP遍历文件夹下的文件和获取到input name的值

    <?php$dir = dirname(__FILE__); //要遍历的目录名字 ->当前文件所在的文件夹//$dir='D:\PHP\wamp\www\admin\hosts\admi ...

  6. JAVA 遍历文件夹下的所有文件(递归调用和非递归调用)

    JAVA 遍历文件夹下的所有文件(递归调用和非递归调用) 1.不使用递归的方法调用. public void traverseFolder1(String path) { int fileNum = ...

  7. PHP遍历文件夹下所有文件

    不论是面试还是正常工作需要都会用到遍历文件夹下的所有文件,今天就记录一下笔记.废话不多说直接上代码: <?php /** * 遍历当前文件夹展示所有的文件和目录 */ function dirL ...

  8. opencv实现遍历文件夹下所有文件

    前言 最近需要将视频数据集中的每个视频进行分割,分割成等长的视频片段,前提是需要首先遍历数据集文件夹中的所有视频. 实现 1.了解opencv中的Directory类: 2.实现测试代码: 系统环境 ...

  9. asp.net 遍历文件夹下全部子文件夹并绑定到gridview上

    遍历文件夹下所有子文件夹,并且遍历配置文件某一节点中所有key,value并且绑定到GridView上 Helper app_Helper = new Helper(); DataSet ds = n ...

随机推荐

  1. noip模拟题 Market

    题面描述: 数据范围: Solution: 我们发现\(v\)很小,但是\(M\)很大,考虑转化一下一般的背包 我们用\(f[v]\)来表示拿到价值为\(v\)的物品需要付出的最少代价,特别的,当\( ...

  2. SpringCloud 入门知识篇

    SpringCloud 入门 springcloud 学习 7天学会springcloud 教程 https://www.cnblogs.com/skyblog/category/738524.htm ...

  3. 关于Struts2_2.3.24中FilterDispatcher过期的问题

    今天在使用最新版Struts2.3.24时,总是报出如下警告: ******************************************************************** ...

  4. 解决vuex保存的数据刷新页面时清空

    参考文章: vuex中store保存的数据,刷新页面会清空 主要解决代码: 1.更改store文件下index文件state的定义 const store = new Vuex.Store({ sta ...

  5. box-shadow inset

    安卓支持,ios不支持:box-shadow: 0px 0px 2px inset rgba(0,0,0,0.08); 安卓,ios都支持:box-shadow: inset 0px 0px 2px ...

  6. Web Api试图加载格式不正确的程序,解决方法

    Web Api试图加载格式不正确的程序,错误如下: 问题原因: 出现上述问题的原因是,所加载的程序集中有32位的,也有64位的,IIS 7 程序池 在Windows下.Net FrameWork是64 ...

  7. 【后台管理系统】—— Ant Design Pro 项目爬坑(一)

    1.表单rule中可以分对象处理不同规则 <FormItem label="类型名称" {...formLayout}> { form.getFieldDecorato ...

  8. 解决保存快照失败后redis无法写入的问题( Redis is configured to save RDB snapshots)

    MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk. Com ...

  9. Linux_系统时间管理

    目录 目录 时间管理 date指令 系统时间设置timedatectl指令 本地时间同步 时间服务器NTP RHEL6 RHEL7 计划任务 一次性计划任务 at指令 限制用户建立一次性计划任务 周期 ...

  10. C# user32.dll找窗口时,使用GetClass方法解决 【带有系统自动编译的窗体类后缀名】 问题

    [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] static extern int G ...