likes
comments
collection
share

重学nodejs系列之fs & path & stream(三)

作者站长头像
站长
· 阅读数 3

引言

在 Node.js 开发中,文件系统(fs)、路径处理(path)和流(stream)是常见而重要的模块,提供了强大的文件处理和流处理能力。

文件系统(fs)模块

1. 文件读写操作

1.1 读取文件内容

使用 fs.readFile 方法可以异步地读取文件的内容:

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 方法可以异步地写入文件内容:

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 方法可以创建目录:

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 方法可以读取目录中的文件列表:

fs.readdir(path.join(__dirname, 'fsdir'), (err, files) => {
  if (err) throw err;
  console.log('目录中的文件列表:', files);
});

3. 文件和目录的权限控制

3.1 设置文件权限

使用 fs.chmod 方法可以设置文件的权限:

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]): 将所有给定的路径片段连接在一起,构成一个规范化的路径。
import path from 'path';

const fullPath = path.join(__dirname, 'files', 'example.txt');
console.log(fullPath);

这个经常使用,我上面使用fs的时候就用到了 路径解析:

  • path.resolve([...paths]): 将路径或路径片段的序列解析为绝对路径。
import path from 'path';

const resolvedPath = path.resolve('files', 'example.txt');
console.log(resolvedPath);

流(stream)模块

在 Node.js 中,流(Stream)是处理流式数据的一种抽象接口。流可以是可读的、可写的,或者两者兼备。使用流可以提高应用程序的性能和效率,特别是在处理大量数据时。

可读流(Readable Streams):

  • 可读流用于从源读取数据。在流模块中,fs.createReadStream 用于创建可读流。
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 用于创建可写流。
import fs from 'fs';
import path from 'path'

const writableStream = fs.createWriteStream(path.join(__dirname, 'fs.txt'));
writableStream.write('写入一段流数据');
writableStream.end();

管道流(Piping):

  • 管道是将可读流和可写流连接在一起的机制,用于直接将数据从一个流传输到另一个流,而不需要手动处理和管理数据的缓冲。
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 类用于创建自定义转换流。
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'(当发生错误时触发)等。
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数据