目录
Buffer 缓存区
Buffer 简介
JavaScript 语言自身只有字符串数据类型,没有二进制数据类型。但在处理像TCP流或文件流时,必须使用到二进制数据。因此在 Node.js中,定义了一个 Buffer 类,该类用来创建一个专门存放二进制数据的缓存区。
Buffer (缓存区或者缓冲区),是一个类似于Array的对象, 用于表示固定长度的字节序列. 主要处理文件流和二进制数据流.
Buffer 也可以理解为固定长度的内存空间.
Buffer 特点:
- 大小固定无法调整.
- 性能好,可以对内存直接操作.
- 每个元素的大小为1字节(byte). 1 byte=8 bit
Stream 流
Stream和Buffer
- 流(Stream)就是一系列从A点到B点移动的数据
两者间的联系:
- 数据的传输分为:数据送达和处理
1. 数据量较小,送达比处理更快,需要等待数据处理完毕
2. 数据量较大,处理比送达更快,需要等待数据的完整送达 那么这两个等待的过程,就需要在Buffer缓冲区中
fs 文件操作
fs
Node.js 把所有对文件操作的API都封装在了 fs (file system) 模块中, 该模块提供的所有文件操作的方法都有同步和异步两个版本.
建议大家使用异步方法,比起同步,异步方法性能更高,速度更快,而且没有阻塞
如果要是用fs模块, 首先需要导入该模块.
const fs = require('fs');
fs.openSync()
同步打开文件 fs.openSync(path[, flags, mode])
- path - 文件的路径, 不可省略.
- flags - 文件打开的行为。默认值是r
- mode - 设置文件模式(权限),文件创建默认权限为 0666(可读,可写)。
- 返回值为<number>:表示文件描述符的整数
flags 参数
Flag | 描述 |
---|---|
r | 以只读模式打开文件。文件必须存在。如果文件不存在,会抛出异常 |
r+ | 以读写模式打开文件。文件必须存在。 |
rs | 以同步方式只读打开文件。阻塞操作,但在某些操作系统上可能会提供更好的稳定性。 |
rs+ | 以同步方式读写打开文件。阻塞操作,但在某些操作系统上可能会提供更好的稳定性。 |
w | 以只写模式打开文件。如果文件不存在则创建文件,如果文件存在则截断文件。 |
wx | 类似于 'w',但如果路径存在,则失败。 |
w+ | 以读写模式打开文件。如果文件不存在则创建文件,如果文件存在则截断文件。 |
wx+ | 类似于'w+',但如果路径存在,则失败。 |
a | 以追加模式打开文件。如果文件不存在则创建文件。 |
ax | 类似于'a',但如果路径存在,则失败。 |
a+ | 以读取和追加模式打开文件。如果文件不存在则创建文件。 |
ax+ | 类似于'a+',但如果路径存在,则失败。 |
fs.open()
异步打开文件 fs.open(path, flags[, mode], callback)
- path - 文件的路径, 不可省略.
- flags - 文件打开的行为,不可省略.
- mode - 设置文件模式(权限),文件创建默认权限为 0666(可读,可写)。
- callback - 回调函数, 不可省略. 带有两个参数如:callback(err, fd)。err异常出错信息. fd <integer>,打开后的文件标识
const fs = require('fs');
fs.open("./openText.txt",'a',(err,fd)=>{
if(err){
return console.error(err);
}
console.log("文件打开成功!",fd);
})
关闭文件
同步关闭文件 fs.closeSync(fd)
- fd:表示要关闭的文件标识
const fs = require('fs');
const myFile = fs.openSync("./openText.txt",'a');
fs.closeSync(myFile);
异步关闭文件 fs.close(fd,callback)
- fd:表示要关闭的文件标识
- callback: 异步关闭文件的回调函数.
运行结果:
异步模式下写入文件
fs.writeFile(file, data[, options], callback)
- file - 文件名或文件描述符。
- data - 要写入文件的数据,可以是 String(字符串) 或 Buffer(缓冲) 对象。
- options - 该参数是一个对象,包含 {encoding, mode, flag}。默认编码为 utf8, 模式为 0666 , flag 为 'w'
- callback - 回调函数,回调函数只包含错误信息参数(err),在写入失败时返回。写入失败 err为错误对象, 写入成功err为null
写法一:
const fs = require('fs');
fs.open("./openText.txt",'a',(err,fd)=>{
if(err){
return console.error(err);
}
console.log("文件打开成功!",fd);
let fileData="文件系统";
fs.writeFile(fd,fileData,(err)=>{
//写入失败 err为错误对象,写入成功err为null
if(err){
console.log("写入失败");
}else{
console.log("写入成功");
}
})
fs.close(fd,(err)=>{
if(err){
return console.error(err);
}else{
console.log("文件关闭成功!",fd);
}
});
})
原文件
运行结果:
保持着异步打开文件是‘a’追加的写入模式
写法二:
const fs = require('fs');
fs.writeFile("./openText.txt", '文件系统', (err) => {
//写入失败 err为错误对象,写入成功err为null
if (err) {
console.log("写入失败");
} else {
console.log("写入成功");
}
})
运行结果:
再次查看文件,可以看到之前的内容被覆盖掉了
异步模式下读取文件
fs.readFile(path[, options], callback)
- path <string> | <Buffer> | <URL> | <integer> 文件名或文件描述符
- options <Object> | <string>
- encoding <string> | <null> 默认值: null
- flag <string> 请参阅对文件系统 flags 的支持。 默认值: 'r'。
- signal <AbortSignal> 允许中止正在进行的读取文件
- callback <Function>
- err <Error> | <AggregateError>错误信息
- data <string> | <Buffer> 读取文件内容, buffer类型
const fs = require('fs');
fs.readFile("./openText.txt",(err,data)=>{
if(err){
console.log("文件读取失败");
}else{
console.log(data.toString());
}
})
运行结果:
异步删除文件
fs.unlink(path, callback)
- path - 文件路径。
- callback - 回调函数。
const fs = require('fs');
fs.unlink('./openText1.txt',function(err,){
if(err){
console.log("删除失败");
}else{
console.log("删除成功");
}
});
运行结果:
异步读取目录
fs.readdir(path[, options], callback)
- path - 文件路径。
- options <string> | <Object>
- encoding <string> 默认值: 'utf8'
- withFileTypes <boolean> 默认值: false (如果 options.withFileTypes 设置为 true,则 files 数组将包含 <fs.Dirent> 对象)
- callback - 回调函数,回调函数带有两个参数err, files.
- err 为错误信息
- files 为 目录下的文件数组列表。
const fs = require('fs');
fs.readdir('./',function(err,files){
if(err){
return console.log(err);
}else{
console.log(files);
}
});
Stream 流
概念
Stream 就是一系列从A点到B点移动的数据, 实际移动的过程中, 把大块的数据分割为小块, 进行定向且有序的传输.
fs流--是Node.js的抽象接口.
流的类型:
- readable -可读的流(例如 fs.createReadStream())。
- writable - 可写的流(例如 fs.createWriteStream())。
- duplex - 可读写的流(例如 net.Socket)。
- transform -在读写过程中可以修改和变换数据的 Duplex 流(如 zlib.createDeflate())。
流的事件:
- 所有的 stream 对象都是事件发射器 EventEmitter 的实例,发射的常用事件有:data 事件、end 事件、error 事件、finish 事件等
创建流
常见创建流的两种方式
可读流
创建 fs 可读流,用于从流中读取数据。
客户端的 HTTP 响应,服务器的HTTP 请求, fs 的读取流等都是可读流的例子。
语法格式:
fs.createReadStream(path[, options])
可写流
可写流也叫写入流,创建 fs 可写流,可用于向流中写入数据。 语法格式如下:
fs.createWriteStream(path[, options])
fs.createWriteStream()
fs.createWriteStream(path[, options])
- path <string> | <Buffer> | <URL>文件路径
- options <string> | <Object>
- flags <string> 请参阅对文件系统 flags 的支持。 默认值: 'w'。
- encoding <string> 默认值: 'utf8'
- fd <integer> | <FileHandle> 默认值: null
- mode <integer> 默认值: 0o666
- autoClose <boolean> 默认值: true
- emitClose <boolean> 默认值: true
- start <integer>
- fs <Object> | <null> 默认值: null
- 返回值: <fs.WriteStream>
const fs = require('fs');
const writeStream = fs.createWriteStream('./myFile.txt');
writeStream.write("创建流");
writeStream.write("可写流");
运行结果:
fs.createReadStream()
fs.createReadStream(path[, options])
- path <string> | <Buffer> | <URL> 文件路径
- options <string> | <Object>
- flags <string> 请参阅对文件系统 flags 的支持。 默认值: 'r'。
- encoding <string> 默认值: null
- fd <integer> | <FileHandle> 默认值: null
- mode <integer> 默认值: 0o666
- autoClose <boolean> 默认值: true
- emitClose <boolean> 默认值: true
- start <integer>
- end <integer> 默认值: Infinity
- highWaterMark <integer> 默认值: 64 * 1024
- fs <Object> | <null> 默认值: null
- 返回值: <fs.ReadStream>
const fs = require('fs');
const readStream = fs.createReadStream('./myFile.txt');
let data = '';
//当文件有数据触发 data 事件
readStream.on('data',function(chunk){
data += chunk;
console.log(data);
});
const fs = require('fs');
const readStream = fs.createReadStream('./myFile.txt');
let data = '';
//当文件没有数据触发 end 事件
readStream.on('end',function(){
console.log("该文件没有内容!");
});
const fs = require('fs');
const readStream = fs.createReadStream('./myFile.txt');
let data = '';
//当文件打开错误触发该事件
readStream.on('error',function(err){
console.log(err.stack);
});
其他流的方式
管道流
管道流是可读流的一种方法,将可读流与可写流进行管道方式的绑定,将可读流信息通过管道方式写入可写流的一种数据写入方式。
语法格式:
readable.pipe(destination[,options])
链式流
链式流一般用于管道操作,在单个可读流上绑定多个可写流的流操作链。
管道流
const fs = require('fs');
//创建一个可读流 readerStream
const readerStream = fs.createReadStream('input.txt');
//创建一个可写流 writeStream
const writeStream = fs.createWriteStream('output.txt');
//进行管道读写操作读取“input.txt”文件内容,并将其写入到“output.txt”中
readerStream.pipe(writeStream);
console.log("程序执行完毕");
END