引言
在 Node.js 开发中,文件系统(fs)、路径处理(path)和流(stream)是常见而重要的模块,提供了强大的文件处理和流处理能力。
文件系统(fs)模块
1. 文件读写操作
1.1 读取文件内容
使用 fs.readFile
方法可以异步地读取文件的内容:
ts
import fs from 'fs';
import path from 'path';
fs.readFile(path.join(__dirname, 'fs.txt'), 'utf8', (err, data) => {
if (err) throw err;
console.log('文件内容:', data);
});
1.2 写入文件内容
使用 fs.writeFile
方法可以异步地写入文件内容:
ts
import fs from 'fs';
import path from 'path';
fs.writeFile(path.join(__dirname, 'fs.txt'), 'Hello, Node.js!', 'utf8', (err) => {
if (err) throw err;
console.log('文件已写入');
});
fs.appendFile(path.join(__dirname, 'fs.txt'), 'typescript', 'utf-8', (err) => {
if (err) throw err;
console.log('文件已追加');
})
2. 目录操作
2.1 创建目录
使用 fs.mkdir
方法可以创建目录:
ts
import fs from 'fs';
import path from 'path';
fs.mkdir(path.join(__dirname, 'fsdir'), (err) => {
if (err) throw err;
console.log('目录已创建');
});
2.2 读取目录内容
使用 fs.readdir
方法可以读取目录中的文件列表:
ts
fs.readdir(path.join(__dirname, 'fsdir'), (err, files) => {
if (err) throw err;
console.log('目录中的文件列表:', files);
});
3. 文件和目录的权限控制
3.1 设置文件权限
使用 fs.chmod
方法可以设置文件的权限:
ts
import fs from 'fs';
import path from 'path';
fs.chmod(path.join(__dirname, 'fsdir/fs.ts'), 0o755, (err) => {
if (err) throw err;
console.log('文件权限已设置');
});
fs模块除了异步回调的使用方式外,还可以是使用同步,只需要在异步方法后面加个Sync
。
路径处理(path)模块
路径拼接:
path.join([...paths])
: 将所有给定的路径片段连接在一起,构成一个规范化的路径。
ts
import path from 'path';
const fullPath = path.join(__dirname, 'files', 'example.txt');
console.log(fullPath);
这个经常使用,我上面使用fs的时候就用到了 路径解析:
path.resolve([...paths])
: 将路径或路径片段的序列解析为绝对路径。
ts
import path from 'path';
const resolvedPath = path.resolve('files', 'example.txt');
console.log(resolvedPath);
流(stream)模块
在 Node.js 中,流(Stream)是处理流式数据的一种抽象接口。流可以是可读的、可写的,或者两者兼备。使用流可以提高应用程序的性能和效率,特别是在处理大量数据时。
可读流(Readable Streams):
- 可读流用于从源读取数据。在流模块中,
fs.createReadStream
用于创建可读流。
ts
import fs from 'fs';
import path from 'path'
const readableStream = fs.createReadStream(path.join(__dirname, 'fs.txt'));
readableStream.on('data', (chunk) => {
console.log(chunk);
// <Buffer 48 65 6c 6c 6f 2c 20 4e 6f 64 65 2e 6a 73 21 74 79 70 65 73 63 72 69 70 74>
});
readableStream.on('end', () => {
console.log('完成');
});
可写流(Writable Streams):
- 可写流用于将数据写入目标。在流模块中,
fs.createWriteStream
用于创建可写流。
ts
import fs from 'fs';
import path from 'path'
const writableStream = fs.createWriteStream(path.join(__dirname, 'fs.txt'));
writableStream.write('写入一段流数据');
writableStream.end();
管道流(Piping):
- 管道是将可读流和可写流连接在一起的机制,用于直接将数据从一个流传输到另一个流,而不需要手动处理和管理数据的缓冲。
ts
import fs from 'fs';
import path from 'path'
const readableStream = fs.createReadStream(path.join(__dirname, 'fs.txt'));
const writableStream = fs.createWriteStream(path.join(__dirname, 'fs2.txt'));
readableStream.pipe(writableStream);
转换流(Transform Streams):
- 转换流是一种特殊的可读可写流,它可以在读取和写入过程中对数据进行转换。
stream.Transform
类用于创建自定义转换流。
ts
import { Transform } from 'stream';
const upperCaseTransform = new Transform({
transform(chunk, encoding, callback) {
const upperCaseChunk = chunk.toString().toUpperCase();
this.push(upperCaseChunk);
callback();
}
});
process.stdin.pipe(upperCaseTransform).pipe(process.stdout);
在控制台输入小写字母,回车后会被转换为大写字母 流事件(Stream Events):
- 流对象触发各种事件,例如
'data'
(当数据可用时触发)、'end'
(当没有更多数据可读时触发)、'error'
(当发生错误时触发)等。
ts
import fs from 'fs';
import path from "path"
const readableStream = fs.createReadStream(path.join(__dirname, 'fs.txt'));
readableStream.on('data', (chunk) => {
console.log('chunk:', chunk);
});
readableStream.on('end', () => {
console.log('读操作完成');
});
readableStream.on('error', (error) => {
console.error('Error:', error.message);
});
stream操作里面的chunk都是buffer数据