记一次Node.js读取文件数据并去重写入数据库的学习笔记
在小程序云开发和前后端统一的大势席卷下,学习Node.js已经是前端、小程序开发的必备技能了。
而且,由于小程序能够被轻松反编译的情况下,云开发能够为程序提供最后的一层保障,所以我们有必要学习Node.js。
本文为一次Node.js实现一个小功能的学习文章。
一:背景
最近手痒,于是找同事用python扒了一下某个社区的用户昵称和头像数据。
当然,并不能直接拿到别人库中的用户昵称及头像,于是扒的是发的消息,然后过滤了消息内容,留下了用户昵称和头像。
这里面重复数据有很多,于是准备用Node.js来去重,并实现以下2个目标:
1、将去重后的数据写入到新文件中
2、将去重后的数据写入数据库中。
二:数据格式
看一眼数据格式,如下图。
数据格式1.png
三:准备
首先,我们要选择模块,Node.js已经为我们准备了很多很好用的模块了。
1、涉及到读写文件的,那就必要要用fs模块。
2、涉及到数据库,于是这里用的数据库是mysql,模块选择mysql,当然用其他也是可以的。
3、此外,还需要用到readline这个模块,这个是逐行读取数据的。如果不用这个模块的话,那我们用fs读到的数据是全部的数据,我们还要对数据进行去重并写到数据库中!很显然,单单fs模块很难做到(也可以说是我水平不够,毕竟刚刚学,如果fs能够轻松做到逐行读取数据,那就欢迎指出!),最好的方式就是把数据逐行读取到数组中。
单单用fs做的一个demo,试试看。
let fs = require('fs');
fs.readFile('./test.txt','utf-8',(err,data)=>{
if(err){
console.log(err);
}else{
console.log(data);
}
})
console.log('here is first executed');
/**
text.txt的内容为
Hello,Node.js
Hello,JavaScript
Hello,MY IDE
可以看到,上面的小demo是读取完之后将数据以参数的形式传给回调函数的。
最后输出的,也是全部的数据。
*/
将上方代码保存为main.js,看下它的输出截图。
main.png
四:代码解析
1、引入及定义变量
// 三个模块必须要引入
const readline = require('readline');
const fs = require('fs');
const ms = require('mysql');
let mysql; // mysql连接实例
let userInfo = []; // 将所有数据逐行push进来
let newarr = []; // 去重后的数据数组
2、用fs模块创建读取流并让readline对象监听
具体可以看这里Node.js v10.14.2文档 readline
let input = fs.createReadStream("info2.txt");
const rl = readline.createInterface({
input: input
});
rl.on('line', (line) => {
// 每读取一行,都触发此监听事件
});
rl.on('close', (line) => {
// 读取完毕之后触发
});
3、实现readline对象的2个监听事件
在这里,我们需要实现,将数据读取到数组userInfo中,并在读取完毕之后进行去重,将去重的数据保存到newarr中。
rl.on('line', (line) => {
// 这里很简单,直接Push进userInfo中就可以了。
userInfo.push(line);
});
rl.on('close', (line) => {
console.log('line=' + line);
// 去重,并读取userInfo的长度和newarr的长度
newarr = norepeat1(userInfo);
console.log('newarr.length = ' + newarr.length);
console.log('userinfo.length = ' +userInfo.length);
console.log("读取完毕!");
// 连接数据库
mysql = ms.createConnection({
host:'127.0.0.1',
user:'root',
password:'root',
database:'xzw'
})
// 调用写方法函数(及写入数据库)
writeNew()
});
// 去重函数
function norepeat1(arr){
return [...new Set(arr)];
}
给看一下userInfo和newarr的长度,可以看出,活跃的永远都是少数啊。
去重.png
4、实现写方法writeNew
到这一步,我们已经成功了一半了。
function writeNew(){
newarr.forEach(element => {
// 插入数据库
let line = element;
// 解析出需要的数据
let [namestr,avatarstr] = line.split(';');
let name = namestr.split('=')[1];
let avatar = avatarstr.split('=')[1];
// 构造sql
let querystr = 'insert into qsbk_user(username,avatar) value(?,?)';
let params = [name,avatar];
mysql.query(querystr,params,function(err,result){
if(err){
// 在这里我们可以将失败的消息输出,然后执行完毕后可以手动处理这部分问题。
// 这里如果用的是for的话,还可以直接定位到行哦
console.log('errormessage=' + err.message);
console.log('error,name=' + name + ';avatar=' + avatar);
}
// else 没有消息就是最大的好消息
})
// 写入文件
// 写文件的时候需要注意2点
//1、window需要在每行数据之后拼接 "\r\n",不然不会自动换行, linux "\n" mac "\r"
//2、fs用的是appenFile才会在文本文件的后边添加,用writeFile是覆盖添加。
let content = element + "\r\n";
fs.appendFile('ouput.txt',content,function(err,data){
//
})
});
}
看一看数据库记录截图。
数据库.png
五:后记
由于没有python部分代码,如果有学习需要的,可以在我的资料中添加我微信,拿info2.txt文件(仅限学习使用!!!)
当然啦,这部分数据也没多少商用价值,打歪主意就算了吧。去重后也就100多条数据!