使用nodejs进行了简单的文件分卷工具
关键词:node fs readline generator
(在这之前需要声明的是这篇博客的应用范围应该算是相当狭隘,写出来主要也就是给自己记录一下临时兴起写的一个小工具,仅从功能需求上来说我相信是不适用于大多数读者的,欢迎有兴趣看的朋友给我做一次review)
最近沉迷漫画,收集了一堆野生资源,偶尔会遇到一些四格漫画,观看体验不是很好,因为每话篇幅比较短,就独立成了一个目录,譬如这样:
const fs = require('fs');
const readline = require('readline');
/**
* @description 获取questtion的返回
* @param {String} question 用户提示
* @param {Function} handler 验证用户输入
* @returns {Promise} rl.question方法本身是通过回调来处理用户输入的,所以选择了返回promise来做阻塞,有序地抛出question并接收answer
*/
function getQuestionResult(question,handler){
return new Promise((res)=>{
// 创建一个可读流,用来读取在cmd中的输入
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
/**
* 考虑到即使用户输入异常,question方法都会在监听到换行之后结束,所以把handleResult的结构设计成一个对象,
* 由一个状态值success来表示是否通过handler的校验,success为false时应再次执行并且获取用户输入 */
rl.question(question, async (ans)=>{
const handleResult = handler(ans)
if (handleResult.success){
rl.close()
res(handleResult.value)
} else {
//handleResult.success为false时,handleResult.value是handler中设置的错误提示
rl.close()
const rejecthandle = await getQuestionResult(handleResult.value,handler)
res(rejecthandle)
}
})
})
}
// 这里创建一个generator实例,我觉得generator的yield单向有序的特性很适合我这个需求
function*gen(){
function getChangeSettingsFlag(ans){
return ans==="Y"?{success:true,value:true}:{success:true,value:false}
}
const getPath = function (ans) {
/**
* @description 验证路径(是否是目录)
* @param {String} path
*/
const validatePath = function (path) {
try {
// node10.x及以下版本不支持readdirSync,需要你需要这种写法,在运行之前需要切换node版本
const dir = fs.readdirSync(path)
if (dir) {
return {success:true,value:path}
}
} catch(err){
return {success:false,value:"提供的地址不合理,请重新输入:"}
}
}
return validatePath(ans)
}
// yield并不会返回值,这里声明的changeSettingFlag的值实际上是接收的next方法的参数
const changeSettingFlag = yield getChangeSettingsFlag
const settings = {
volumeSize: 10,
dirName: "新建分卷"
}
// 改变预设
if (changeSettingFlag){
const volumeSize = yield function(volumeSize){
return Number(volumeSize)>0&&Number(volumeSize)!==Infinity?{success:true,value:volumeSize}:{success:false,value:"输入的数字不合理,请重新输入:"}
}
settings.volumeSize = Number(volumeSize)||settings.volumeSize
const dirName = yield function(dirName){
return dirName.trim()?{success:true,value:dirName}:{success:false,value:"输入的目录名不合理,请重新输入:"}
}
settings.dirName = dirName.trim()||settings.dirName
}
// 接收路径
const pathInfo = {
input: "",
output: ""
}
const inputPath = yield getPath
pathInfo.input = inputPath;
const outputPath = yield getPath
pathInfo.output = outputPath;
const conf = {
pathInfo,
settings
}
console.log("conf",conf)
yield conf
}
// run it
async function workflow(generator){
const func0 = generator.next().value
const changeSettingFlag = await getQuestionResult("当前预设置如下:\n\t输出的分卷名:“新建分卷”;\n\t容量:10话/卷;\n希望调整预设吗?(Y/n) ",func0)
let getvolumeSize,getdirName
if (changeSettingFlag){
const func1 = generator.next(changeSettingFlag).value
getvolumeSize = await getQuestionResult("期望的卷容量(话/卷)是: ",func1)
const func2 = generator.next(getvolumeSize).value
getdirName = await getQuestionResult("期望的分卷名是:",func2)
}
const func3 = generator.next(getdirName).value
const inputPath = await getQuestionResult("选择的源路径是:",func3)
const func4 = generator.next(inputPath).value
const outputPath = await getQuestionResult("期望的输出路径是:",func4)
const conf = generator.next(outputPath).value
// 当前计数,通过在文件名中添加count来保持排序
let currentCount = 0;
// 当前分卷
let currentVolume = 0;
/**
* @param {String} path
* @param {String} newFolderName
*/
async function letsdance(path,newFolderName="") {
const childs = fs.opendirSync(path)
let chunkNum = 0 let newFolderPath = newFolderName
for await (const dirent of childs) {
if (dirent.isDirectory()) {
// 填充满一个目录之后创建一个新目录
if (currentVolume%conf.settings.volumeSize===0) {
chunkNum+=1;
newFolderPath = conf.pathInfo.output+"/"+conf.settings.dirName+"_"+chunkNum
fs.mkdirSync(newFolderPath)
// 如果你不希望命名后缀一直递增,也可以在新建目录之后把currentCount重新置为0
}
currentVolume+=1
const nextLevelPath = path+"/"+dirent.name
letsdance(nextLevelPath,newFolderPath)
} else if (dirent.isFile()){
currentCount += 1
const extName = dirent.name.split(".").reverse()[0]
const targetFilePath = path+"/"+dirent.name
const newFileName = newFolderPath+"/"+currentCount+"."+extName
fs.copyFileSync(targetFilePath,newFileName)
}
}
}
letsdance(conf.pathInfo.input)
}
const g = gen()
workflow(g)
运行这个脚本,如果我有两个目录,需要将他们之中的文件复制到一个新目录来实现合并的效果的话,在讲第一个目录的文件按原顺序命名为1-n之后。第二个目录的文件则会从n+1开始命名,效果如下:
使用nodejs进行了简单的文件分卷工具的更多相关文章
- java简单的文件读写工具类
import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.BufferedRead ...
- 用nodejs搭建一个简单的服务器
使用nodejs搭建一个简单的服务器 nodejs优点:性能高(读写文件) 数据操作能力强 官网:www.nodejs.org 验证是否安装成功:cmd命令行中输入node -v 如果显示版本号表示安 ...
- 拿nodejs快速搭建简单Oauth认证和restful API server攻略
拿nodejs快速搭建简单Oauth认证和restful API server攻略:http://blog.csdn.net/zhaoweitco/article/details/21708955 最 ...
- 用nodejs搭建一个简单的服务监听程序
作为一个从业三年左右的,并且从事过半年左右PHP开发工作的前端,对于后台,尤其是对以js语言进行开发的nodejs,那是比较有兴趣的,虽然本身并没有接触过相关的工作,只是自己私下做的一下小实验,但是还 ...
- 利用 nodeJS 搭建一个简单的Web服务器(转)
下面的代码演示如何利用 nodeJS 搭建一个简单的Web服务器: 1. 文件 WebServer.js: //-------------------------------------------- ...
- nodejs创建一个简单的web服务
这是一个突如其来的想法,毕竟做web服务的框架那么多,为什么要选择nodejs,因为玩前端时,偶尔想调用接口获取数据,而不想关注业务逻辑,只是想获取数据,使用java或者.net每次修改更新后还要打包 ...
- 使用jsp/servlet简单实现文件上传与下载
使用JSP/Servlet简单实现文件上传与下载 通过学习黑马jsp教学视频,我学会了使用jsp与servlet简单地实现web的文件的上传与下载,首先感谢黑马.好了,下面来简单了解如何通过使用 ...
- Mac OS环境下媒体文件分割工具mediafilesegmenter的简单使用(生成M3U8 TS文件)
mediafilesegmenter是苹果开发的一款用于分割媒体文件的工具,其功能与mediastreamsegmenter相似,但操作更简单. * 具体可以对比博客中的另一篇简介<Mac OS ...
- Spring简单的文件配置
Spring简单的文件配置 “计应134(实验班) 凌豪” 一.Spring文件配置 spring至关重要的一环就是装配,即配置文件的编写,接下来我按刚才实际过程中一步步简单讲解. 首先,要在web. ...
随机推荐
- js map & Number
js map & Number const regionIds = `1,2,3`; // "1,2,3" regionIds.split(',').map(Number) ...
- 网站资源被盗链的:预防方法 VS 网站资源防盗链的:破解技巧
1 www.cnblogs.com 发布文章使用:只允许注册用户才可以访问! 1 资源被盗链:(简明定义) 下载者不是从你的网站直接下载资源,而是通过其他盗链网站提供的你的下载资源链接进行下载你的服务 ...
- vue & arrow function error
vue & arrow function error <template> <div class="home"> <img alt=" ...
- flex item default All In One
flex item default All In One flex item default 初始值 === flex: 0 1 auto; https://drafts.csswg.org/css- ...
- codepen iframe theme id
codepen iframe theme id iframe css theme demos See the Pen css margin collapsing (1. 相邻兄弟元素) by xgqf ...
- 如何使用 js 实现一个 Promise.all 方法 PromiseAll
如何使用 js 实现一个 Promise.all 方法 PromiseAll Promise.all PromiseAll https://developer.mozilla.org/en-US/do ...
- Flutter for web
Flutter for web https://flutter.dev/web https://github.com/flutter/flutter_web Dart https://github.c ...
- js 裁剪图片
js 裁剪图片 https://gugeji.com/search?q=js剪切图片
- Google 灭霸 彩蛋
Google 灭霸 彩蛋 在Google中搜索"灭霸",然后在右侧点击的"无限手套",页面的一些搜索项就会随机性像沙子一样的消失(后面统称沙化效果),特别的炫酷 ...
- 牛市下SPC新空投糖果来了
2021年元旦刚过没几天,比特币就开启了牛市的旅程,比特币涨至三万四千美元,率领众多币种暴涨,一股浓浓的牛市味道来了. 虽然从昨天开始,比特币带领着主流币进行了一波调整,但是只涨不跌的市场是 大家说比 ...