【Nodejs】nodejs内置模块(中)

在这里插入图片描述

1.路劲处理模块 path


1.1 模块概览

在nodejs中,path是个使用频率很高,但却让人又爱又恨的模块。部分因为文档说的不够清晰,部分因为接口的平台差异性。将path的接口按照用途归类,仔细琢磨琢磨,也就没那么费解了。

1.2 获取路径/文件名/扩展名

  • 获取路径:path.dirname(filepath)
  • 获取文件名:path.basename(filepath)
  • 获取扩展名:path.extname(filepath)

(1)获取所在路径
例子如下:

var path = require('path');
var filepath = '/tmp/demo/js/test.js';// 输出:/tmp/demo/js
console.log( path.dirname(filepath) );

(2)获取文件名
严格意义上来说,path.basename(filepath) 只是输出路径的最后一部分,并不会判断是否文件名。但大部分时候,我们可以用它来作为简易的“获取文件名“的方法。

var path = require('path');// 输出:test.js
console.log( path.basename('/tmp/demo/js/test.js') );// 输出:test
console.log( path.basename('/tmp/demo/js/test/') );// 输出:test
console.log( path.basename('/tmp/demo/js/test') );

如果只想获取文件名,单不包括文件扩展呢?可以用上第二个参数。

// 输出:test
console.log( path.basename('/tmp/demo/js/test.js', '.js') );

(3) 获取文件扩展名
简单的例子如下:

var path = require('path');
var filepath = '/tmp/demo/js/test.js';// 输出:.js
console.log( path.extname(filepath) );

更详细的规则是如下:(假设 path.basename(filepath) === B )

  • 从B的最后一个.开始截取,直到最后一个字符。
  • 如果B中不存在.,或者B的第一个字符就是.,那么返回空字符串。

直接看官方文档的例子

path.extname('index.html')
// returns '.html'path.extname('index.coffee.md')
// returns '.md'path.extname('index.')
// returns '.'path.extname('index')
// returns ''path.extname('.index')
// returns ''

1.3 路径组合

path.join([...paths])
path.resolve([...paths])

(1) path.resolve() 生成完成的绝对路径
语法格式:

path.resolve([...myPaths])

解释:

  • 将路径或路径片段的序列解析为绝对路径。
  • 返回的路径是从右往左处理,后面的每个 myPath 被依次解析,直到构造出一个完整的绝对路径。

你可以想象现在你在shell下面,从左到右运行一遍cd path命令,最终获取的绝对路径/文件名,就是这个接口所返回的结果了。
代码举例:

const path = require('path');let arr1 = ['/foo1/foo2', 'dselegent', 'foo3'];
let result1 = path.resolve(...arr1);
console.log(result1); // 打印结果:/foo1/foo2/dselegent/foo3let arr2 = ['/foo1/foo2', '/dselegent', 'foo3'];
let result2 = path.resolve(...arr2);
console.log(result2); // 打印结果:/dselegent/foo3
const path = require('path');// 假设当前工作路径是 /Users/a/Documents/git-code/nodejs-learning-guide/examples/2016.11.08-node-path// 输出 /Users/a/Documents/git-code/nodejs-learning-guide/examples/2016.11.08-node-path
console.log( path.resolve('') )// 输出 /Users/a/Documents/git-code/nodejs-learning-guide/examples/2016.11.08-node-path
console.log( path.resolve('.') )// 输出 /foo/bar/baz
console.log( path.resolve('/foo/bar', './baz') );// 输出 /foo/bar/baz
console.log( path.resolve('/foo/bar', './baz/') );// 输出 /tmp/file
console.log( path.resolve('/foo/bar', '/tmp/file/') );// 输出 /Users/a/Documents/git-code/nodejs-learning-guide/examples/2016.11.08-node-path/www/js/mod.js
console.log( path.resolve('www', 'js/upload', '../mod.js') );

(2) path.join() 将多个路径进行拼接
如果是我们手动拼接路径,容易出错。这个时候,可以利用 path.join() 方法将路径进行拼接。

语法格式:

path.join([...paths]);

解释:使用平台特定的分隔符作为定界符将所有给定的 path 片段连接在一起,然后规范化生成的路径。

代码举例:

const path = require('path');const result1 = path.join(__dirname, './app.js');
console.log(result1); // 返回:/Users/smyhvae/dselegent/app.jsconst result2 = path.join('/foo1', 'foo2', './foo3');
console.log(result2); // 返回:/foo1/foo2/foo3const result3 = path.join('/foo1', 'foo2', '/foo3');
console.log(result3); // 返回:/foo1/foo2/foo3

(3) path.resolvepath.join 区别
path.resolvepath.join 都是属于 path 核心模块下的方法,用来拼接路径。

都可以拼接成一个完整路径.

const path = require("path");var dirname = '/User/Desktop';
var basename = 'abc.txt';path.join(dirname, basename);  // /User/Desktop/abc.txtpath.resolve(dirname, basename);  // /User/Desktop/abc.txt

如果 dirname 是以 ./ 、…/、不加 / 开头的话,那么 resolve 会找到磁盘下的根目录

const path = require("path");var dirname = '../User/Desktop';
var basename = 'abc.txt';path.join(dirname, basename);  // ../User/Desktop/abc.txtpath.resolve(dirname, basename);  // /Users/Desktop/node/User/Desktop/abc.txt

如果 basename 是以 / 开头的,那么 resolve 就会直接返回 basename

const path = require("path");var dirname = '/User/Desktop';
var basename = '/abc.txt';path.join(dirname, basename);  // /User/Desktop/abc.txtpath.resolve(dirname, basename);  // /abc.txt

1.4 几个常见路径

__dirname:这是一个常量,表示:当前执行文件所在完整目录。
__filename:这是一个常量。表示:当前执行文件的完整目录 + 文件名。
process.cwd:获取当前执行 Node命令 时的目录名。
代码举例:

console.log(__dirname);
console.log(__filename);
console.log(process.cwd());

运行结果:

$ node app.js/Users/smyhvae/dselegent
/Users/smyhvae/dselegent/app.js
/Users/smyhvae/dselegent

2.本地文件操作模块 fs


Node.js 中的同步和异步的区别
fs模块对文件的几乎所有操作都有同步和异步两种形式。例如:readFile()readFileSync()

区别:

  • 同步调用会阻塞代码的执行,异步则不会。
  • 异步调用会将 读取任务 下达到任务队列,直到任务执行完成才会回调。
  • 异常处理方面:同步必须使用 try catch 方式,异步可以通过回调函数的第一个参数。【★★★★★

2.1 文件读取

同步读取

var fs = require('fs');
var data;try{data = fs.readFileSync('./fileForRead.txt', 'utf8');console.log('文件内容: ' + data);
}catch(err){console.error('读取文件出错: ' + err.message);
}

输出如下:

/usr/local/bin/node readFileSync.js
文件内容: hello world

异步读取

var fs = require('fs');fs.readFile('./fileForRead.txt', 'utf8', function(err, data){if(err){return console.error('读取文件出错: ' + err.message);}console.log('文件内容: ' + data);
});

输出如下

/usr/local/bin/node readFile.js
文件内容: hello world

fs/promises 从 Node.js 14 开始可用 从 Node.js 14 开始,fs 模块提供了两种使用基于 promises 的文件系统的方法。这些 promises 可以通过 require('fs').promises 或 require('fs/promises') 获得。

import { readFile } from 'fs/promises';try {const contents = await readFile(filePath, { encoding: 'utf8' });console.log(contents);
} catch (err) {console.error(err.message);
}

2.2 文件写入

备注:以下代码,如果文件不存在,则创建文件;如果文件存在,则覆盖文件内容;

异步写入

var fs = require('fs');fs.writeFile('./fileForWrite.txt', 'hello world', 'utf8', function(err){if(err) throw err;console.log('文件写入成功');
});

同步写入

var fs = require('fs');try{fs.writeFileSync('./fileForWrite1.txt', 'hello world', 'utf8');console.log('文件写入成功');
}catch(err){throw err;
}

promises

import { writeFile } from 'fs/promises';try {const contents = await writeFile('message.txt', 'hello world', { encoding: 'utf8' });console.log(contents);
} catch (err) {// When a request is aborted - err is an AbortErrorconsole.error(err);
}

2.3 文件是否存在

fs.exists()已经是deprecated状态,现在可以通过下面代码判断文件是否存在。

异步本

const fs = require('fs')//检查文件是否存在于当前目录中
fs.access('package.json', fs.constants.F_OK, err => {if(err) {console.log('package.json不存在于当前目录中')return}console.log('package.json存在于当前目录中')
})fs.access('index.js', fs.constants.F_OK, err => {if(err) {console.log('index.js不存在于当前目录中')return}console.log('index.js存在于当前目录中')
})

fs.access()除了判断文件是否存在(默认模式),还可以用来判断文件的权限。

备忘:fs.constants.F_OK等常量无法获取(node v6.1,mac 10.11.4下,fs.constantsundefined

同步

import { accessSync, constants } from 'fs';try {accessSync('etc/passwd', constants.R_OK );console.log('can read');
} catch (err) {console.error('no access!');
}

promises

import { access, constants } from 'node:fs/promises';try {await access('/etc/passwd', constants.R_OK);console.log('can access');
} catch {console.error('cannot access');
}

2.4 删除文件

异步版本

var fs = require('fs');fs.unlink('./fileForUnlink.txt', function(err){if(err) throw err;console.log('文件删除成功');
});

同步版本

import { unlinkSync } from 'fs';try {unlinkSync('/tmp/hello');console.log('successfully deleted /tmp/hello');
} catch (err) {// handle the error
}

promises

import { unlink } from 'fs/promises';try {await unlink('/tmp/hello');console.log('successfully deleted /tmp/hello');
} catch (err) {// handle the error
}

2.5 创建目录

异步版本(如果目录已存在,会报错)

// fs.mkdir(path[, mode], callback)
var fs = require('fs');fs.mkdir('sub', function(err){if(err) throw err;console.log('创建目录成功');
});

同步版本

// fs.mkdirSync(path[, mode])
var fs = require('fs');try{fs.mkdirSync('hello');console.log('创建目录成功');
}catch(e){throw e;
}

promises

import { mkdir } from 'fs/promises';try {const createDir = await mkdir(projectFolder, { recursive: true });console.log(`created ${createDir}`);
} catch (err) {console.error(err.message);
}

2.6 遍历目录

同步版本,注意:fs.readdirSync()只会读一层,所以需要判断文件类型是否目录,如果是,则进行递归遍历。

// fs.readdirSync(path[, options])
var fs = require('fs');
var path = require('path');
var getFilesInDir = function(dir){var results = [ path.resolve(dir) ];var files = fs.readdirSync(dir, 'utf8');files.forEach(function(file){file = path.resolve(dir, file);var stats = fs.statSync(file);if(stats.isFile()){results.push(file);}else if(stats.isDirectory()){results = results.concat( getFilesInDir(file) );}});return results;
};
var files = getFilesInDir('../');
console.log(files);

2.7 读取目录

import { readdir } from 'fs/promises';try {const files = await readdir(path);for (const file of files)console.log(file);
} catch (err) {console.error(err);
}

2.8 删除目录

// 删除目录(前提没有文件在里面)
fs.rmdir('./avatar', err => {if (err && err.code === 'ENOENT') {console.log('目录不存在');}
});

2.9 删除整个目录

//1
const fs = require("fs")
fs.("./avatar",(err,data)=>{// console.log(data)data.forEach(item=>{fs.unlinkSync(`./avatar/${item}`)})fs.rmdir("./avatar",(err)=>{console.log(err)})
})//2
const fs = require('fs')
fs.readdir("./avatar").then(async (data)=>{let arr = []data.forEach(item=>{arr.push(fs.unlink(`./avatar/${item}`))})await Promise.all(arr)fs.rmdir("./avatar")
})//3
const fs = require('fs').promises;
fs.readdir('./image2').then(async data => {await Promise.all(data.map(item => fs.unlink(`./image2/${item}`)));await fs.rmdir('./image2');
});

2.10 文件重命名

异步版本

// fs.rename(oldPath, newPath, callback)
var fs = require('fs');fs.rename('./hello', './world', function(err){if(err) throw err;console.log('重命名成功');
});

同步版本

// fs.renameSync(oldPath, newPath)
var fs = require('fs');fs.renameSync('./world', './hello');
promisesimport { rename } from 'fs/promises';try {await rename('./world', './hello');console.log(`rename`);
} catch (err) {console.error(err.message);
}

2.11 获取文件状态

(1)异步:fs.stat(path,callback): path是一个表示路径的字符串,callback接收两个参数(err,stats),其中stats就是fs.stats的一个实例;

(2)同步:fs.statSync(path) 只接收一个path变量,fs.statSync(path)其实是一个fs.stats的一个实例;

方法

  • stats.isFile() – 是否文件
  • stats.isDirectory() – 是否目录
// Node.js program to demonstrate the 
// fs.statSync() method // Import the filesystem module 
const fs = require('fs'); // Getting information for a file 
statsObj = fs.statSync("test_file.txt"); console.log(statsObj);  
console.log("Path is file:", statsObj.isFile()); 
console.log("Path is directory:", statsObj.isDirectory()); // Getting information for a directory 
statsObj = fs.statSync("test_directory"); console.log(statsObj); 
console.log("Path is file:", statsObj.isFile()); 
console.log("Path is directory:", statsObj.isDirectory());

输出:

Stats {dev:3229478529,mode:33206,nlink:1,uid:0,gid:0,rdev:0,blksize:4096,ino:1970324837039946,size:0,blocks:0,atimeMs:1582306776282,mtimeMs:1582482953967,ctimeMs:1582482953968.2532,birthtimeMs:1582306776282.142,atime:2020-02-21T17:39:36.282Z,mtime:2020-02-23T18:35:53.967Z,ctime:2020-02-23T18:35:53.968Z,birthtime:2020-02-21T17:39:36.282Z
}
Path is file:true
Path is directory:false
Stats {dev:3229478529,mode:16822,nlink:1,uid:0,gid:0,rdev:0,blksize:4096,ino:562949953486669,size:0,blocks:0,atimeMs:1582482965037.8445,mtimeMs:1581074249467.7114,ctimeMs:1582482964979.8303,birthtimeMs:1582306776288.1958,atime:2020-02-23T18:36:05.038Z,mtime:2020-02-07T11:17:29.468Z,ctime:2020-02-23T18:36:04.980Z,birthtime:2020-02-21T17:39:36.288Z
}
Path is file:false
Path is directory:true

2.12 追加文件内容

fs.appendFile(file, data[, options], callback)

  • file:可以是文件路径,也可以是文件句柄。(还可以是buffer?)
  • data:要追加的内容。string或者buffer。
  • options
    • encoding:编码,默认是utf8
    • mode:默认是0o666
  • flag:默认是a

注意:如果file是文件句柄,那么

  • 开始追加数据前,file需要已经打开。
  • file需要手动关闭。
var fs = require('fs');
fs.appendFile('./extra/fileForAppend.txt', 'hello', 'utf8', function(err){if(err) throw err;console.log('append成功');
});

3.事件机制模块 events


Node.js 有多个内置的事件,我们可以通过引入events模块,并通过实例化EventEmitter类来绑定和监听事件,如下实例:

// 引入 events 模块
var EventEmitter = require('events');
// 创建 eventEmitter 对象
var event = new EventEmitter();

以下程序绑定事件处理程序:

// 绑定事件及事件的处理程序
eventEmitter.on('eventName', eventHandler);

我们可以通过程序触发事件:

// 触发事件
eventEmitter.emit('eventName');

EventEmitter的每个事件由一个事件名和若干个参数组成,事件名是一个字符串,通常表达一定的语义。对于每个事件,EventEmitter 支持 若干个事件监听器。

当事件触发时,注册到这个事件的事件监听器被依次调用,事件参数作为回调函数参数传递。

让我们以下面的例子解释这个过程:

// 引入 events 模块
var EventEmitter = require('events');
// 创建 eventEmitter 对象
var event = new EventEmitter();
event.on('someEvent', function(arg1, arg2) { console.log('listener1', arg1, arg2); 
}); 
event.on('someEvent', function(arg1, arg2) { console.log('listener2', arg1, arg2); 
}); 
event.emit('someEvent', 'arg1 参数', 'arg2 参数'); 

执行以上代码,运行的结果如下:

$ node event.js 
listener1 arg1 参数 arg2 参数
listener2 arg1 参数 arg2 参数

以上例子中,event为事件someEvent注册了两个事件监听器,然后触发了 someEvent 事件。

运行结果中可以看到两个事件监听器回调函数被先后调用。 这就是EventEmitter最简单的用法。

EventEmitter提供了多个属性,如onemiton函数用于绑定事件函数,emit属性用于触发一个事件

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/7792.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

计算机网络模型

计算机网络模型 网络模型网络模型中各层对应的协议封装与分用TCP/IP协议簇的组成 网络模型 OSI 七层模型 应用层、表示层、会话层、传输层、网络层、数据链路层、物理层 TCP/IP四层模型 应用层、传输层、网络层、网络接口层 TCP/IP五层模型 应用层、传输层、网络层、数据链路…

iOS transform rotate总结

研究了一下transform的旋转设置,调了半天还以为是旋转写错了,发现是两个不同的view对象写错了,不管怎么说,还是记录一下旋转相关的操作吧。 参数都是弧度。 以一个图片来举例。 let img UIImageView.init() img.image UIImage…

k8s集群环境的搭建

1.环境规划 1.1 集群类型 Kubernetes集群大致分为两类:一主多从和多主多从。 一主多从:一个Master节点和多台Node节点,搭建简单,但是有单机故障风险,适合用于测试环境。 多主多从:多台Master和多台Node节点…

ubuntu与windows之间的文件共享

最近在做项目,需要用到ubuntu进行代码编译生成可执行文件,但是我个人阅读和编写代码喜欢用source insight这个软件IDE。安利一下这个软件,阅读代码和编辑代码真的很棒啊,谁用谁知道吧! 由于在ubuntu中安装source insig…

RocketMQ基本概念与入门

文章目录 MQ基本结构依赖案例:productConsumer 核心概念1.nameserver2.broker3.主题队列4.queue队列5. 生产者6.消费者分组和生产者分组7.消费点位 MQ基本结构 message: 消息数据对象product: 程序代码,生成消息,发送消息到队列consumer: 程序代码,监听(绑定)队列,获取消息,执行…

全志F1C200S嵌入式驱动开发(spi-nor image制作)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 一般soc系统里面添加spi-nor flash芯片,特别是对linux soc来说,都是把它当成文件系统来使用的。spi-nor flash和spi-nand flash相比,虽然空间小了点,但是胜在稳定,这是很多工业…

(二)RabbitMQ【安装Erlang、安装RabbitMQ 、账户管理、管控台、Docker安装 】

Lison <dreamlison163.com>, v1.0.0, 2023.06.22 RabbitMQ【安装Erlang、安装RabbitMQ 、账户管理、管控台、Docker安装 】 文章目录 RabbitMQ【安装Erlang、安装RabbitMQ 、账户管理、管控台、Docker安装 】**安装Erlang**安装RabbitMQ账户管理管控台Docker安装RabbitM…

大数据技术之Hive2

目录标题 3、Hive 数据类型3.1 基本数据类型&#xff1a;3.2 集合数据类型&#xff1a;3.3 类型转化 4、DDL数据定义4.1 创建数据库4.2 查询数据库4.3 创建表4.4 管理表4.5 外部表4.6 管理表与外部表的相互转换4.7 分区表4.7.1 分区表基本操作4.7.2 分区表注意事项 4.7 修改表4…

【后端面经】微服务架构(1-4) | 降级:为什么每次大促的时候总是要把退款之类的服务停掉?

文章目录 一、 前置知识1、什么是降级?2、降级的典型应用3、为什么要降级?4、降级的分类5、如何降级?A) 降级的应用场景B) 跨服务降级C) 提供有损服务二、面试环节1、面试准备2、基本流程3、亮点方案A) 读写服务降级写服务B) 快慢路径降级慢路径三、章节汇总 在熔断章…

Flutter Widget Life Cycle 组件生命周期

Flutter Widget Life Cycle 组件生命周期 视频 前言 了解 widget 生命周期&#xff0c;对我们开发组件还是很重要的。 今天会把无状态、有状态组件的几个生命周期函数一起过下。 原文 https://ducafecat.com/blog/flutter-widget-life-cycle 参考 https://api.flutter.dev/f…

chrome解决http自动跳转https问题

1.地址栏输入&#xff1a; chrome://net-internals/#hsts 2.找到底部Delete domain security policies一栏&#xff0c;输入想处理的域名&#xff0c;点击delete。 3.再次访问http域名不再自动跳转https了。

【Linux后端服务器开发】HTTPS协议

目录 一、加密算法 二、中间人攻击 三、CA认证 一、加密算法 HTTPS协议是什么&#xff1f;HTTPS协议也是一个应用层协议&#xff0c;是在HTTP协议的基础上引入了一个加密层。 HTTP协议内容是按照文本的方式明文传输的&#xff0c;这就导致在传输过程中出现一些被篡改的情况…

vray GPU渲染如何设置?最适合 VRay 渲染的 GPU 是什么?

Chaos 提供的 Vray GPU是一个独立的渲染引擎&#xff0c;提供 GPU 硬件加速。它还与 CPU&#xff08;处理器&#xff09;配合使用&#xff0c;并利用 CPU 和 GPU 硬件进行无缝混合渲染。 GPU 渲染使 Vray GPU 渲染引擎能够在系统的 GPU 而不是 CPU 上执行光线跟踪计算。由于 G…

STM32MP157驱动开发——按键驱动(阻塞与非阻塞)

“阻塞与非阻塞 ”机制&#xff1a; 阻塞&#xff1a; 使用 休眠唤醒机制&#xff0c;read函数会休眠&#xff0c;是阻塞的使用 poll 时&#xff0c;如果传入的超时时间不为 0&#xff0c;表示 read函数会休眠&#xff0c;这种访问方法也是阻塞的。 非阻塞 使用 poll 时&am…

解析数据可视化工具:如何选择最合适的软件

在当今信息爆炸的时代&#xff0c;数据已成为各行各业的重要资源。为了更好地理解和分析数据&#xff0c;数据可视化成为一种必不可少的工具。市面上数据可视化工具不说上千也有上百&#xff0c;什么帆软、powerbi、把阿里datav&#xff0c;腾讯云图、山海鲸可视化等等等等&…

N位分频器的实现

N位分频器的实现 一、 目的 使用verilog实现n位的分频器&#xff0c;可以是偶数&#xff0c;也可以是奇数 二、 原理 FPGA中n位分频器的工作原理可以简要概括为: 分频器的作用是将输入时钟频率分频,输出低于输入时钟频率的时钟信号。n位分频器可以将输入时钟频率分频2^n倍…

redis中缓存雪崩,缓存穿透,缓存击穿的原因以及解决方案

一 redis的缓存雪崩 1.1 缓存雪崩 在redis中&#xff0c;新&#xff0c;旧数据交替时候&#xff0c;旧数据进行了删除&#xff0c;新数据没有更新过来&#xff0c;造成在高并发环境下&#xff0c;大量请求查询redis没有数据&#xff0c;直接查询mysql&#xff0c;造成mysql的…

算法竞赛入门【码蹄集新手村600题】(MT1040-1060)

算法竞赛入门【码蹄集新手村600题】(MT1040-1060&#xff09; 目录MT1041 求圆面积和周长MT1042 求矩形的面积和周长MT1043 椭圆计算MT1044 三角形面积MT1045 平行四边形MT1046 菱形MT1047 梯形MT1048 扇形面积MT1049 三角形坐标MT1050 空间三角形MT1051 四边形坐标MT1052 直角…

LabVIEW使用支持向量机对脑磁共振成像进行图像分类

LabVIEW使用支持向量机对脑磁共振成像进行图像分类 医学成像是用于创建人体解剖学图像以进行临床研究、诊断和治疗的技术和过程。它现在是医疗技术发展最快的领域之一。通常用于获得医学图像的方式是X射线&#xff0c;计算机断层扫描&#xff08;CT&#xff09;&#xff0c;磁…

Python基于PyTorch实现循环神经网络回归模型(LSTM回归算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 LSTM网络是目前更加通用的循环神经网络结构&#xff0c;全称为Long Short-Term Memory&#xff0c;翻…