以文件流的方式读取文件内容

目录结构

|— 16.createStream.js

|— blood.lrc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
const fs = require("fs");
const path = require("path");
const iconv = require("iconv-lite");
const filename = path.join(__dirname,"./blood.lrc");
//创建一个文件读取流
let stream = fs.createReadStream(filename);
//让文件流通过iconv过滤编码
stream = stream.pipe(iconv.decodeStream("gbk"));
let content = "";
stream.on("data",(chunk) => {
content += chunk;
});
//读取结束
stream.on("end",() => {
console.log(content);
})

我们来执行一下它

1
2
3
4
5
6
7
$ node 16-createStream.js
[ti:血染的风采]
[ar:黄耀明]
...中间省略
[03:19.42] 共和国的旗帜上有我们血染的风采
[03:25.51] * * *
[03:32.98] ---End---

我们尝试着让歌词滚动显示

|— 17-showLyric.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
const fs = require("fs");
const path = require("path");
const iconv = require("iconv-lite");
const filename = path.join(__dirname,"./blood.lrc");
fs.readFile(filename,(err,data) => {
if(err) throw err;
let lines = iconv.decode(data,"gbk").split("\n");
//[00:32.67] 也许我告别 将不再回来
let regexp = /\[(\d{2}):(\d{2})\.(\d{2})]\s(.+)/;
let start = new Date().getTime();
//遍历
lines.forEach((line) => {
// [00:32.67] 也许我告别 将不再回来
let matches = regexp.exec(line);
if(matches){
let min = matches[0];
let sec = parseFloat(matches[2]);
let ms = parseFloat(matches[3]);
let lyric = matches[4];
let time = min * 60 * 1000 + sec * 1000 + ms;
//当前歌词不是立即执行,由于下达任务的时刻不同我们要设置时间偏移量
let offset = new Date().getTime();
setTimeout(() => {
console.log(lyric)
},time - offset);
}else{
//不是一句歌词
console.log(line);
}
})
})

执行16.showLyric.js

1
2
3
4
5
6
7
8
9
10
$ node 17-showLyric.js
[ti:血染的风采]
[ar:黄耀明]
[al:人山人海]
[offset:500]
[00:55.04]中文歌词库 www.CnLyric.com
歌曲:血染的风采
歌手:黄耀明
^C

我们成功了。

我们以上拆分歌词是用split("\n")拆分成数组,然后再遍历每一句这样做的。然而node给我们提供了一个模块叫做readline.我们下面用readline模块完成同样的业务。

18-readline.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
//readline实现一行一行读取歌词
const fs = require("fs");
const path = require("path");
const iconv = require("iconv-lite");
const readline = require("readline");
const filename = path.join(__dirname,"./blood");
const readStream = fs.createReadStream(filename)
.pipe(iconv.decodeStream("gbk"));
let rl = readline.createInterface({input:readStream});
let regexp = /\[(\d{2}):(\d{2})\.(\d{2})]\s(.+)/;
let start = new Date().getTime();
rl.on("line",(line) => {
if(matches){
let min = parseFloat(matches[1]);
let sec = parseFloat(matches[2]);
let ms = parseFloat(matches[3]);
let lyric = matches[4];
let time = min * 60 * 1000 + sec * 1000 + ms;
//当前歌词不是立即执行,由于下达任务的时刻不同我们要设置时间偏移量
let offset = new Date().getTime() - start;
setTimeout(() => {
console.log(lyric);
},time - offset);
}else{
//不是一句歌词
console.log(line);
}
})

执行18-readline.js

1
2
3
4
5
6
7
8
9
10
$ node 18-readline.js
[ti:血染的风采]
[ar:黄耀明]
[al:人山人海]
[offset:500]
[00:55.04]中文歌词库 www.CnLyric.com
歌曲:血染的风采
歌手:黄耀明
^C


本文结束,感谢阅读。

本文作者:melody0z
本文链接:https://melodyvoid/Node/reads-file-contents-in-a-file-stream.html
欢迎转载,转载请注明文本链接

坚持原创技术分享,您的支持将鼓励我继续创作!