如何在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的资料请关注我们其它相关文章!

时间: 2021-05-04

使用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)与流(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模块(二)

前一篇学习了文件的打开和关闭,文件操作总不能只包含打开和关闭吧,这里就开始文件的读写操作. 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使用方法详解

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

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

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

NodeJS学习笔记之FS文件模块

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

NodeJS实现自定义流的方法

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

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

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

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

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

详解node服务器中打开html文件的两种方法

本文介绍了详解node服务器中打开html文件的两种方法,分享给大家,具体如下: 方法1:利用 Express 托管静态文件,详情查看这里 方法2:使用fs模块提供的readFile方法打开文件,让其以text/html的形式输出. 代码: var express = require('express'); var fs=require("fs"); var app = express(); //方法1:通过express.static访问静态文件,这里访问的是ajax.html //

详解SQL Server数据库状态和文件状态

数据库状态 (database states) 查询数据库的当前状态 : 1.查询所有数据库的状态 ,通过sys.databases目录视图的state_desc列 user master go select state_desc ,[name] from sys.databases go 2.查询指定数据库的状态,通过DATABASEPROPERTYEX函数的Status属性 select DATABASEPROPERTYEX('demoData','status') go 状态: ONLIN

详解PHP防止直接访问.php 文件的实现方法

详解PHP防止直接访问.php 文件的实现方法 为了保证我们用 PHP 写的 API 的安全性要禁止除了接口外的访问方式. 比如我们的项目为 example, 其下有文件夹 dir1.有个接口文件 api.php. 结构为: 输入图片说明 这时候我们要求只能通过 example/api.php 来调用file.php里的服务,不能直接通过example/dir1/file.php来访问. 在 php 里有这样一个变量$_SERVER,这是个数组变量, 里面有各种键值对, 具体的可以搜索一下资料.

详解配置 Apache 服务器支持 PHP 文件的解析

详解配置 Apache 服务器支持 PHP 文件的解析 [说明] 1. 本例中 Apache 版本为 httpd-2.4.20-x64-vc14 ,安装路径为 E:\Apache24 2. PHP 版本为 php-5.5.34-Win32-VC11-x64 ,安装路径为 E:\php-5.5.34 [下载] 登录 http://php.NET/downloads.php 下载 PHP,由于我要把它跟 Apache 集成,所以我这里下载的是 Thread Safe 版本: [安装] 1. 解压下载

详解C 语言项目中.h文件和.c文件的关系

详解C 语言项目中.h文件和.c文件的关系 在编译器只认识.c(.cpp))文件,而不知道.h是何物的年代,那时的人们写了很多的.c(.cpp)文件,渐渐地,人们发现在很多.c(.cpp)文件中的声明语句就是相同的,但他们却不得不一个字一个字地重复地将这些内容敲入每个.c(.cpp)文件.但更为恐怖的是,当其中一个声明有变更时,就需要检查所有的.c(.cpp)文件. 于是人们将重复的部分提取出来,放在一个新文件里,然后在需要的.c(.cpp)文件中敲入#include XXXX这样的语句.这样即

详解如何修改 node_modules 里的文件

前言 有时候使用npm上的包,发现有bug,我们知道如何修改,但是别人可能一时半会没法更新,或者是我们特殊需求,别人不愿意修改,这时候我们只能自己动手丰衣足食.那么我们应该如何修改别人的源码呢?首先,直接修改node_modules里面的文件是不太行的,重新安装依赖就没有了.一般常用办法有两个: 下载别人代码到本地,放在src目录,修改后手动引入. fork别人的代码到自己仓库,修改后,从自己仓库安装这个插件. 这两个办法的缺陷就是:更新麻烦,我们每次都需要手动去更新代码,无法与插件同步更新.如

实例详解Nodejs 保存 payload 发送过来的文件

1:接受文件 http://stackoverflow.com/questions/24610996/how-to-get-uploaded-file-in-node-js-express-app-using-angular-file-upload 可以用下列的第三方库 •busboy and connect-busboy •multiparty and connect-multiparty •formidable •multer 2:保存文件 ps:nodejs get/request 灌水评

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

fs模块是一个比较庞大的模块,在前面也介绍了该模块中最核心的一点东西,虽然核心的这点东西,在整个fs模块中占据的比例比较小,但是如果只是我们平常使用的话,基本已经够用了,其他的一些方法,属于能力提升时需要学习的的内容了,所以在后面就不再继续了,本篇属于fs模块中的最后一篇,也不是把fs模块中的其他API都给一一列举出来,这里再说最后一个我看来很重要的方法,监听文件或者目录的的方法watchFile. 概总 这里之所以在最后把这个watchFile方法写入到这里,是因为在前端的一个流行的构建工具g