资讯专栏INFORMATION COLUMN

【Node文件系统fs模块】

MyFaith / 2805人阅读

摘要:一个例子测试返回值当缓存区写满时,输出一个例子当缓存区数据全部输出时,触发事件系统缓存区数据已经全部输出。数据可读文件读取完成系统缓存区数据已经全部输出。要写入的数据文件已经打开,文件描述符是文件系统模块同步更新

环境:Node v8.2.1; Npm v5.3.0; OS Windows10

1、fs 模块API

nodejs的文件操作大部分API都提供了同步和异步的两种方式,下面是异步API结构图,同步方法在异步方法后面加【Sync】就行了

1.1 API结构图

1.2 文件读写模式对应编码

2、一些例子

下面是部分API的例子,对部分API的一个简单代码实现

2.1 readFile读取文件
//readFile(filename,[options],callback);

/**
 * filename, 必选参数,文件名
 * [options],可选参数,可指定flag(文件操作选项,如r+ 读写;w+ 读写,文件不存在则创建)及encoding属性
 * callback 读取文件后的回调函数,参数默认第一个err,第二个data 数据
 */

const fs = require("fs");
fs.readFile("./package.json",{flag:"r+",encoding:"utf8"},(err,data)=>{
    if(err)
        throw err;
    console.log(data);
})
2.2 writeFile写文件
// fs.writeFile(filename,data,[options],callback);
/**
 * filename, 必选参数,文件名
 * data, 写入的数据,可以字符或一个Buffer对象
 * [options],flag,mode(权限),encoding
 * callback 读取文件后的回调函数,参数默认第一个err,第二个data 数据
 */

const fs = require("fs");
const data="hello world";
const bf=Buffer.from(data);
//buffer写入
fs.writeFile("./test.txt",bf,err=>{
    if(err)
        throw err;
    console.log("写入成功");
})

//字符写入
fs.writeFile("./test.txt",data,err=>{
    if(err)
        throw err;
    console.log("写入成功");
})
2.3 以追加方式写文件
// fs.appendFile(filename,data,[options],callback);
const fs = require("fs");
const data = " hello world";
const bf = Buffer.from(data);
//buffer
fs.appendFile("./test.txt", bf, err => {
    if (err)
        throw err;
    console.log("追加成功");
})

fs.appendFile("./test.txt", data, err => {
    if (err)
        throw err;
    console.log("追加成功");
})
2.4 open打开文件

打开文件,获取文件描述

// fs.open(filename, flags, [mode], callback);

/**
 * filename, 必选参数,文件名
 * flags, 操作标识,如"r",读方式打开
 * [mode],权限,如777,表示任何用户读写可执行
 * callback 打开文件后回调函数,参数默认第一个err,第二个fd为一个整数,表示打开文件返回的文件描述符,window中又称文件句柄
 */

const fs = require("fs");
fs.open("./test.txt","r",0666,(err,fd)=>{
    if(err)
        throw err;
    console.log(fd);    //3
})

【0666】为【文件权限码】,也可以在【fs.constants】中输出

2.5 读文件,读取打开的文件内容到缓冲区中
//fs.read(fd, buffer, offset, length, position, callback);
/**
 * fd, 使用fs.open打开成功后返回的文件描述符
 * buffer, 一个Buffer对象,v8引擎分配的一段内存
 * offset, 整数,向缓存区中写入时的初始位置,以字节为单位
 * length, 整数,读取文件的长度
 * position, 整数,读取文件初始位置;文件大小以字节为单位
 * callback(err, bytesRead, buffer), 读取执行完成后回调函数,bytesRead实际读取字节数,被读取的缓存区对象
 */
const fs = require("fs");
fs.open("./test.txt", "r", (err, fd) => {
    if (err)
        throw err;
    let bf = Buffer.alloc(255);
    fs.read(fd,bf,0,9,0,(err,bytesRead,buffer)=>{
        if(err)
            throw err;
        console.log(bytesRead);
        console.log(buffer.toString());
    })
})
2.6 写文件,将缓冲区内数据写入使用fs.open打开的文件
//fs.write(fd, buffer, offset, length, position, callback);

/**
 * fd, 使用fs.open打开成功后返回的文件描述符
 * buffer, 一个Buffer对象,v8引擎分配的一段内存
 * offset, 整数,从缓存区中读取时的初始位置,以字节为单位
 * length, 整数,从缓存区中读取数据的字节数
 * position, 整数,写入文件初始位置;
 * callback(err, written, buffer), 写入操作执行完成后回调函数,written实际写入字节数,buffer被读取的缓存区对象
 */
const fs = require("fs");
fs.open("./test.txt", "w", (err, fd) => {
    if (err)
        throw err;
    let bf = Buffer.from(" 写入文件数据的内容");
    fs.write(fd, bf, 0, bf.length, 0, (err, bytesWritten, buffer) => {
        if (err)
            throw err;
        console.log(bytesWritten);
        console.log(`写入的内容:${buffer.toString()}`);
    })
})
2.7 刷新缓存区

使用fs.write写入文件时,操作系统是将数据读到内存,再把数据写入到文件中,当数据读完时并不代表数据已经写完,因为有一部分还可能在内在缓冲区内。
因此可以使用fs.fsync方法将内存中数据写入文件;--刷新内存缓冲区;

//fs.fsync(fd, [callback])
/**
 * fd, 使用fs.open打开成功后返回的文件描述符
 * [callback(err, written, buffer)], 写入操作执行完成后回调函数,written实际写入字节数,buffer被读取的缓存区对象
 */

const fs = require("fs");
fs.open("./test.txt", "a+", (err, fd) => {
    if (err)
        throw err;
    let bf = Buffer.from(" I love Node");
    fs.write(fd, bf, 0, bf.length, 0, (err, bytesWritten, buffer) => {
        if (err)
            throw err;
       fs.fsync(fd,(err)=>{});
       fs.close(fd,err=>{});
    })
})
2.8 读取目录
//使用fs.readdir读取目录,重点其回调函数中files对象
//fs.readdir(path, callback);

/**
 * path, 要读取目录的完整路径及目录名;
 * [callback(err, files)], 读完目录回调函数;err错误对象,files数组,存放读取到的目录中的所有文件名
 */
const fs = require("fs"),
    path = require("path");
fs.readdir(__dirname + "/../11文件系统fs", (err, files) => {
    if (err)
        throw err;
    files.forEach(file => {
        let filePath = path.normalize(__dirname + "/" + file);
        fs.stat(filePath, (err, stats) => {
            if (stats.isFile()) {
                console.log(filePath + " is: " + "file");
            }
            if (stats.isDirectory()) {
                console.log(filePath + " is: " + "dir");
            }
        })
    })
})
3、流操作 3.1 创建读取流
//fs.createReadStream(path, [options])
/**
 * path 文件路径
 * [options] flags:指定文件操作,默认"r",读操作;encoding,指定读取流编码;autoClose, 是否读取完成后自动关闭,默认true;start指定文件开始读取位置;end指定文件开始读结束位置
 */
const fs = require("fs");
const rs = fs.createReadStream("./package.json", { flags: "r" });
rs.on("open", fd => console.log("开始读取文件"));
rs.on("data", data => {
    console.log(data.toString());
})
rs.on("end", function () {
    console.log("读取文件结束")
});
rs.on("close", function () {
    console.log("文件关闭");
});
rs.on("error", function (err) {
    console.error(err);
});  
3.2 创建写入流
//fs.createWriteStream(path, [options])
/**
 * path 文件路径
 * [options] flags:指定文件操作,默认"w",;encoding,指定读取流编码;start指定写入文件的位置
 */

/* ws.write(chunk, [encoding], [callback]);
 * chunk,  可以为Buffer对象或一个字符串,要写入的数据
 * [encoding],  编码
 * [callback],  写入后回调
 */

/* ws.end([chunk], [encoding], [callback]);
 * [chunk],  要写入的数据
 * [encoding],  编码
 * [callback],  写入后回调
 */
const fs = require("fs");
const ws=fs.createWriteStream("./test.txt",{flags:"w"})
const bf=Buffer.from("I Love Node");
ws.on("open", function () {
    console.log("文件流开启")
});
ws.on("close", function () {
    console.log("文件流关闭");
});
ws.on("error", function (err) {
    console.error(err);
});  
ws.write(bf,"utf8",(err,buffer)=>{
    console.log("写入完成")
})
ws.end(" Bye");
3.3 使用流复制文件

流复制文件就是创建一个读取流和一个写入流,将读取流中的流出的数据用写入流进行写入

//使用流复制文件
const fs = require("fs");

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

const ws = fs.createWriteStream("./package1.json");

rs.on("data", data => {
   ws.write(data);
})

ws.on("open", function (fd) {
    console.log("要写入的数据文件已经打开,文件描述符是: " + fd);
  });
  
rs.on("end",()=>{
    console.log("文件读取完成");
    ws.end("完成",()=>{
        console.log("文件写入完成");
    })
})

关于WriteStream对象的write方法返回一个布尔类型,当缓存区中数据全部写满时,返回false;表示缓存区已经写满,并将立即输出到目标对象中。

一个例子测试返回值:

const fs = require("fs");

var ws = fs.createWriteStream(__dirname + "/test.txt",{flags:"w"});

for (var i = 0; i < 10000; i++) {
  var w_flag = ws.write(i.toString());
  //当缓存区写满时,输出false
  console.log(w_flag);
}

一个例子当缓存区数据全部输出时,触发事件

const fs = require("fs");

const rs = fs.createReadStream("./ABoy.mp3");

const ws = fs.createWriteStream("./ABoy1.mp3");

rs.on("data", data => {
    let t = ws.write(data);
    if(!t){
        console.log(t);
    }
})

ws.on("drain", () => {
    console.log("系统缓存区数据已经全部输出。")
})
3.4 pipe管道用于流

上面使用一个读取流额一个写入流进行了一次文件的复制,还有另外一种方式就是在写入流和读取流之间建立一条管道,是读取流中的数据通过管道源源不断的流向写入流,实现文件的复制。

const fs = require("fs");

const rs = fs.createReadStream("./ABoy.mp3");

const ws = fs.createWriteStream("./ABoy1.mp3");

rs.pipe(ws);

rs.on("data", function (data) {
    console.log("数据可读")
});

rs.on("end", function () {
    console.log("文件读取完成");
});

ws.on("drain", () => {
    console.log("系统缓存区数据已经全部输出。")
});

ws.on("open", function (fd) {
    console.log("要写入的数据文件已经打开,文件描述符是: " + fd);
});

CSDN 【Node文件系统fs模块】同步更新

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/88733.html

相关文章

  • 认识node核心模块--从Buffer、Stream到fs

    摘要:端输入数据到端,对就是输入流,得到的对象就是可读流对就是输出端得到的对象是可写流。在中,这四种流都是的实例,它们都有事件,可读流具有监听数据到来的事件等,可写流则具有监听数据已传给低层系统的事件等,和都同时实现了和的事件和接口。 原文地址在我的博客 node中的Buffer和Stream会给刚接触Node的前端工程师们带来困惑,原因是前端并没有类似概念(or 有我们也没意识到)。然而,...

    TANKING 评论0 收藏0
  • Node.js 高级进阶之 fs 文件模块学习

    摘要:回调函数提供两个参数和,表示有没有错误发生,是文件内容。文件关闭第一个参数文件时传递的文件描述符第二个参数回调函数回调函数有一个参数错误,关闭文件后执行。 showImg(//img.mukewang.com/5d3f890d0001836113660768.jpg); 人所缺乏的不是才干而是志向,不是成功的能力而是勤劳的意志。 —— 部尔卫 文章同步到github博客:https:/...

    verano 评论0 收藏0
  • Node.js学习总结

    摘要:表示当前正在执行的脚本的文件名。默认编码为模式为,为回调函数,回调函数只包含错误信息参数,在写入失败时返回。参数使用说明如下通过方法返回的文件描述符。 Node.js回调 Node.js异步编程的直接体现就是回调。 阻塞代码: const fs = require(fs); let data = fs.readFileSync(input.txt); console.log(data...

    kamushin233 评论0 收藏0
  • Node 基础学习

    摘要:既然这样,怎么理解中的单线程再捋一捋和的关系。在线程上,不会等待操作完成,继续执行后续的代码。这就是单线程异步。在中除了代码,一切都是并行的由于中主任务的执行是以单线程的方式进行,如果程序出错导致崩溃,就会终止整个流程。 node是什么 Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。 Node.js 使用了一个事件驱动、非阻塞式 I/O 的模...

    alaege 评论0 收藏0
  • Node.js 开发指南 读书笔记

    摘要:为指定事件注册一个监听器,接受一个字符串和一个回调函数。发射事件,传递若干可选参数到事件监听器的参数表。为指定事件注册一个单次监听器,即监听器最多只会触发一次,触发后立刻解除该监听器。 1.Node.js 简介 Node.js 其实就是借助谷歌的 V8 引擎,将桌面端的 js 带到了服务器端,它的出现我将其归结为两点: V8 引擎的出色; js 异步 io 与事件驱动给服务器带来极高...

    CocoaChina 评论0 收藏0

发表评论

0条评论

MyFaith

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<