如何在Nodejs中使用模块fs文件系统

概述

node 的fs文档密密麻麻的 api 非常多,毕竟全面支持对文件系统的操作。文档组织的很好,操作基本分为文件操作、目录操作、文件信息、流这个大方面,编程方式也支持同步、异步和 Promise。

本文记录了几个文档中没详细描写的问题,可以更好地串联fs文档思路:

  • 文件描述符
  • 同步、异步与 Promise
  • 目录与目录项
  • 文件信息
  • stream

文件描述符

文件描述符是一个非负整数。它是一个索引值,操作系统可以根据它来找到对应的文件。

在 fs 的很多底层 api 中,需要用到文件描述符。在文档中,描述符通常用fd来代表。例如:fs.read(fd, buffer, offset, length, position, callback)。与这个 api 相对应的是:fs.readFile(path[, options], callback)。

因为操作系统对文件描述符的数量有限制,因此在结束文件操作后,别忘记 close:

const fs = require("fs");

fs.open("./db.json", "r", (err, fd) => {
    if (err) throw err;
    // 文件操作...
    // 完成操作后,关闭文件
    fs.close(fd, err => {
        if (err) throw err;
    });
});

同步、异步与 Promise

所有文件系统的 api 都有同步和异步两种形式。

同步写法

不推荐使用同步 api,会阻塞线程。

try {
    const buf = fs.readFileSync("./package.json");
    console.log(buf.toString("utf8"));
} catch (error) {
    console.log(error.message);
}

异步写法

异步写法写起来容易进入回调地狱。

fs.readFile("./package.json", (err, data) => {
    if (err) throw err;
    console.log(data.toString("utf8"));
});

(推荐)Promise 写法

在 node v12 之前,需要自己借助 promise 封装:

function readFilePromise(path, encoding = "utf8") {
    const promise = new Promise((resolve, reject) => {
        fs.readFile(path, (err, data) => {
            if (err) return reject(err);
            return resolve(data.toString(encoding));
        });
    });
    return promise;
}

readFilePromise("./package.json").then(res => console.log(res));

在 node v12 中,引入了 fs Promise api。它们返回 Promise 对象而不是使用回调。 API 可通过require('fs').promises访问。如此一来,开发成本更低了。

const fsPromises = require("fs").promises;

fsPromises
    .readFile("./package.json", {
        encoding: "utf8",
        flag: "r"
    })
    .then(console.log)
    .catch(console.error);

目录与目录项

fs.Dir 类:封装了和文件目录相关的操作

fs.Dirent 类:封装了目录项的相关操作。例如判断设备类型(字符、块、FIFO 等)。

它们之间的关系,通过代码展示:

const fsPromises = require("fs").promises;

async function main() {
    const dir = await fsPromises.opendir(".");
    let dirent = null;
    while ((dirent = await dir.read()) !== null) {
        console.log(dirent.name);
    }
}

main();

文件信息

fs.Stats 类:封装了文件信息相关的操作。它在fs.stat()的回调函数中返回。

fs.stat("./package.json", (err, stats) => {
    if (err) throw err;
    console.log(stats);
});

注意,关于检查文件是否存在:

  • 不建议在调用 fs.open()、 fs.readFile() 或 fs.writeFile() 之前使用 fs.stat() 检查文件是否存在。而是应该直接打开、读取或写入文件,如果文件不可用则处理引发的错误。
  • 要检查文件是否存在但随后并不对其进行操作,则建议使用 fs.access()

ReadStream 与 WriteStream

在 nodejs 中,stream 是个非常重要的库。很多库的 api 都是基于 stream 来封装的。例如下面要说的 fs 中的 ReadStream 和 WriteStream。

fs 本身提供了 readFile 和 writeFile,它们好用的代价就是性能有问题,会将内容一次全部载入内存。但是对于几 GB 的大文件,显然会有问题。

那么针对大文件的解决方案自然是:一点点读出来。这就需要用到 stream 了。以 readStream 为例,代码如下:

const rs = fs.createReadStream("./package.json");
let content = "";

rs.on("open", () => {
    console.log("start to read");
});

rs.on("data", chunk => {
    content += chunk.toString("utf8");
});

rs.on("close", () => {
    console.log("finish read, content is:\n", content);
});

借助 stream 的 pipe,一行快速封装一个大文件的拷贝函数:

function copyBigFile(src, target) {
    fs.createReadStream(src).pipe(fs.createWriteStream(target));
}

以上就是如何在Nodejs中使用模块fs文件系统的详细内容,更多关于Nodejs的资料请关注我们其它相关文章!

(0)

相关推荐

  • NodeJs 文件系统操作模块fs使用方法详解

    NodeJs:文件读取API使用方法 - - readFile() 需求:使用Node中提供的文件操作API,读取files目录下的1.txt 文档中文本内容. Node的三个组成部分:ECMAScript核心 + 全局成员 + 核心API成员 核心API成员,在大家安装Node应用程序的时候,就已经安装到了自己的电脑中. 如果想要访问核心成员,直接使用require("核心成员的名称"),就能够导入并使用这些核心成员. const fs = require("fs"

  • NodeJS实现自定义流的方法

    前言 常见的自定义流有四种,Readable(可读流).Writable(可写流).Duplex(双工流)和 Transform(转换流),常见的自定义流应用有 HTTP 请求.响应, crypto 加密,进程 stdin 通信等等. stream 模块介绍 在 NodeJS 中要想实现自定义流,需要依赖模块 stream ,直接引入,不需下载,所有种类的流都是继承这个模块内部提供的对应不同种类的类来实现的. 实现一个自定义可读流 Readable 1.创建自定义可读流的类 MyRead 实现自

  • 详解nodeJs文件系统(fs)与流(stream)

    一.简介 本文将介绍node.js文件系统(fs)和流(stream)的一些API已经参数使用情况. 二.目录 文件系统将介绍以下方法: 1.fs.readFile 2.fs.writeFile 3.fs.open 4.fs.read 5.fs.stat 6.fs.close 7.fs.mkdir 8.fs.rmdir 9.fs.readdir 10.fs.unlink stream流的四种类型readable,writable,duplex,transform以及stream对象的事件. 三.

  • 详解nodejs 文本操作模块-fs模块(一)

    JS的安全性问题,就决定了JS想要取操作数据库操作文件是不可实现的,而Nodejs作为服务端的JS,如果依然不能操作文件,那么又如何称之为服务端语言呢,所以在Nodejs中,提供了一个fs(File System)模块,以实现文件及目录的读写操作. 写在前面 Nodejs的一大优势就在于,支持异步调用,不管是在读取数据库,还是在读取文件时,都可以使用异步的方式进行处理,这样就可以处理高并发的情况,从本篇开始,开始对Nodejs的fs模块中,一些重要的API,结合源码,进行一些说明学习. fs模块

  • 使用nodeJS中的fs模块对文件及目录进行读写,删除,追加,等操作详解

    fs概述 文件 I/O 是由简单封装的标准 POSIX 函数提供的. nodeJS中通过 require('fs') 使用fs模块. 所有的方法都有异步和同步的形式. 异步形式始终以完成回调作为它最后一个参数. 传给完成回调的参数取决于具体方法,但第一个参数总是留给异常. 如果操作成功完成,则第一个参数会是 null 或 undefined //异步示例 var fs = require('fs'); fs.unlink('/tmp/hello', function(err){ if (err)

  • 详解Nodejs 通过 fs.createWriteStream 保存文件

    工作中难免会遇到处理大文件的时候,有这种stream的处理方式,就不需要一次处理太大的文件,从而导致内存不够用,或者内存占用太多. fs.createWriteStream 似乎不会自己创建不存在的文件夹,所以在使用之前需要注意,保存文件的文件夹一定要提前创建. const path = '/xxxxxx/ddd/'; if (!fs.existsSync(path)) { fs.mkdirSync(path); } 创建完文件夹,我们就可以进行文件添加操作了.我们希望在使用文件添加操作的时候是

  • NodeJS学习笔记之FS文件模块

    一,开篇分析 文件系统模块是一个简单包装的标准 POSIX 文件 I/O 操作方法集.可以通过调用 require("fs") 来获取该模块.文件系统模块中的所有方法均有异步和同步版本. (1),文件系统模块中的异步方法需要一个完成时的回调函数作为最后一个传入形参. (2),回调函数的构成由调用的异步方法所决定,通常情况下回调函数的第一个形参为返回的错误信息. (3),如果异步操作执行正确并返回,该错误形参则为null或者undefined.如果使用的是同步版本的操作方法,一旦出现错误

  • 详解nodejs 文本操作模块-fs模块(二)

    前一篇学习了文件的打开和关闭,文件操作总不能只包含打开和关闭吧,这里就开始文件的读写操作. fs模块方法 1:read和readSync方法 该方法,是从文件的指定位置处读取文件,一直读取到文件底部,然后江都区到的内容输出到一个缓存区,使用方法如下: fs.read(fd,buffer,offset,length,position,callback); 在read方法中,支持6个参数: fd参数,是文件描述符,是open方法的回调函数中获取到的,是一个数字. buffer,是一个buffer对象

  • Nodejs读取文件时相对路径的正确写法(使用fs模块)

    在开发Nodejs中,我们往往最常用的模块就是fs核心模块(fs.readFile)来读取文件.代码如下: 但是运行之后,并没有按照想象中一样,读取test.html文件内容,这是一个bug,坑爹的玩意,解决办法: 其实由于运行环境的不同,以上的相对路径的写法导致最后读取的位置是不同的. 正确的写法应该是使用"path.join()"的方式实现:(__dirname表示当前文件的目录名) //require 表示引包,引包就是引用自己的一个特殊功能 var http = require

  • nodejs文件操作模块FS(File System)常用函数简明总结

    件系统操作相关的函数挺多的.首先可以分为两大类. 一类是异步+回调的. 一类是同步的. 在这里只对异步的进行整理,同步的只需要在函数名称后面加上Sync即可 1. 首先是一类最常规的读写函数,函数名称和形式,应该是起源于C语言的. 复制代码 代码如下: fs.open(文件路径,读写标识,[文件mode值,666],回调函数(err,文件句柄fd));          fs.read(文件句柄fd,被写入的buffer,offset,length,position,回调函数(err, byte

随机推荐