node.js

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > node.js > node.js文件读写-fs,Stream文件流

node.js同步/异步文件读写-fs,Stream文件流操作实例详解

作者:奔跑的飞牛

这篇文章主要介绍了node.js同步/异步文件读写-fs,Stream文件流操作,结合实例形式详细分析了node.js针对文件的同步/异步读写与文件流相关操作技巧,需要的朋友可以参考下

文件读写——fs

const fs = require('fs');
const fs = require('fs');
fs.unlink('/tmp/hello', (err) => {
  if (err) throw err;
  console.log('成功删除 /tmp/hello');
});
const fs = require('fs');
try {
  fs.unlinkSync('/tmp/hello');
  console.log('successfully deleted /tmp/hello');
} catch (err) {
  // handle the error
}

异步的文件读取

const fs = require("fs");
fs.readFile("./1.txt",(err,data)=>{
    console.log(data);
})

在这里插入图片描述

我们怎么知道它正确读取到了呢?一堆16进制的buffer.

readFile接收三个参数,必选参数:路径,可选参数:编码,必选参数:回调函数。

const fs = require("fs");
fs.readFile("./1.txt","utf-8",(err,data)=>{
    console.log(data);
})

读取文件

const fs = require("fs");
const fn = async () => {
    const data = await new Promise((resovle,reject) => {
        fs.readFile('1.txt','utf-8',(err,data) => {
            if(err) return reject(err)
            resovle(data)      
        })
    })
    console.log(data,111);
}
console.log(1);
console.log(fn(),222);
console.log(2);

在这里插入图片描述

显然异步读取数据不能这样做,人家本身就是异步的,你还拿异步的去取,肯定靠天吃饭啦。

想要准确的拿数据,还是得遵守async函数的规则,乖乖在它的怀抱下等待。

同步的文件读取

const fs = require("fs");
console.log(1);
const data = fs.readFileSync('1.txt','utf-8')
console.log(data);
console.log(2);

在这里插入图片描述

很愉快的读取到数据,因为是同步,所以后面的代码必须等待前面读取文件成功才能继续执行。如果文件非常大,所以还是乖乖异步吧!

异步的写文件

fs.writeFile(file, data[, options])

如果你把1.txt删了或者路径下没有这个文件的话会自动创建文件

const fs = require("fs");
console.log(1);
const data = '写入测试文字'
fs.writeFile('1.txt',data,res=>{
    console.log(res,11111);
})
console.log(2);

在这里插入图片描述

但是如果仅是这样的话,会把原来的文字覆盖

同步的写文件

fs.writeFileSync(file, data[, options])

const fs = require("fs");
console.log(1);
const data = '写入测试文字'
fs.writeFileSync('1.txt', data, res => {
    console.log(res, 11111);
})
console.log(2);

在这里插入图片描述

因为这个写函数如果没有对应文件会自己新建,所以想报错还真的很难!暂时没有错误示例!

open,打开文件

fs.open(path, flags[, mode], callback)

四个参数,mode是默认的:

具体的参数:

flags 可以是:

这对 NFS 挂载模式下打开文件很有用,因为它可以让你跳过潜在的旧本地缓存。 它对 I/O 的性能有明显的影响,所以除非需要,否则不要使用此标志。

注意,这不会使 fs.open() 进入同步阻塞调用。 如果那是你想要的,则应该使用 fs.openSync()。

mode 可设置文件模式(权限和 sticky 位),但只有当文件被创建时才有效。默认为 0o666,可读写。

特有的标志 ‘x’(在 open(2) 中的 O_EXCL 标志)确保 path 是新创建的。 在 POSIX 操作系统中,path 会被视为存在,即使是一个链接到一个不存在的文件的符号。 该特有的标志有可能在网络文件系统中无法使用。

flags 也可以是一个数字,[open(2)] 文档中有描述; 常用的常量可从 fs.constants 获取。 在 Windows 系统中,标志会被转换为与它等同的替代者,例如,O_WRONLY 转换为 FILE_GENERIC_WRITE、或 O_EXCL|O_CREAT 转换为 CREATE_NEW,通过 CreateFileW 接受。

在 Linux 中,当文件以追加模式打开时,定位的写入不起作用。 内核会忽略位置参数,并总是附加数据到文件的末尾。

callback[err,fa]

// macOS 与 Linux
fs.open('<directory>', 'a+', (err, fd) => {
  // => [Error: EISDIR: illegal operation on a directory, open <directory>]
});
// Windows 与 FreeBSD
fs.open('<directory>', 'a+', (err, fd) => {
  // => null, <fd>
});

fs.read读文件,基于open

参数

参数的值

position 指定从文件中开始读取的位置。 如果 position 为 null,则数据从当前文件读取位置开始读取,且文件读取位置会被更新。 如果 position 为一个整数,则文件读取位置保持不变。

回调有三个参数 (err, bytesRead, buffer)。

如果调用该方法的 util.promisify() 版本,将会返回一个包含 bytesRead 和 buffer 属性的 Promise。

例子:

var fs = require('fs');
fs.open('./1.txt', 'r', function (err, fd) {
    if(err) throw err
    //buf根据你的需要设定每次的读取长度
    var buf = new Buffer.alloc(225);
    //读取fd文件内容到buf缓存区,如果position设置为null就会从最开始的地方开始读
    fs.read(fd, buf, 0, 20, null, function (err, bytesRead, buffer) {
        console.log(buf.slice(0, bytesRead).toString());
        console.log(buf);
    });
});

在这里插入图片描述

fs.write写文件,基于open

参数

参数的值

在 Linux 上,当文件以追加模式打开时,指定位置的写入是不起作用的。 内核会忽略位置参数,并总是将数据追加到文件的末尾。

例子

var fs = require('fs');
fs.open('./1.txt', 'r+', function (err, fd) {
    if(err) throw err
    fs.write(fd, '文件追加字符测试', 20, 'utf-8', (err, written, buffer)=>{
        console.log(err);
        console.log(buffer);
    })
});

写入前,别眨眼:
在这里插入图片描述

写入后的结果,写入位置20,打印err,空,打印buffer,刚才写入的字符串!

在这里插入图片描述

文件流Stream

读取流例子

const fs = require("fs");
console.log(111111);
const read = fs.createReadStream('1.txt')
read.setEncoding('utf-8')
read.resume();//让文件流开始'流'动起来
read.on('data',data =>{//监听读取的数据,如果打印data就是文件的内容
    console.log('正在读');
})
read.on('end', () => { //监听状态
    console.log('文件读取结束');
})
console.log(222222);

我这里准备了2万+行的数据,监听的data打印了多少次就说明被流监听了多少次,期间就可以使用多少次这个数据,用于一些超大型的数据读取还是非常有效的。

在这里插入图片描述

写入流

const fs = require("fs");
console.log(111111);
const read = fs.createReadStream('1.txt')
read.setEncoding('utf-8')
read.resume();//让文件流开始'流'动起来
read.on('data',data =>{
    console.log('正在读');
})
read.on('end', () => { //监听状态
    console.log('文件读取结束');
})
console.log(222222);
console.log(333333);
const write = fs.createWriteStream('2.txt')
read.pipe(write) //pipe就是那根水管,抽向2.txt
console.log(444444);

如果你自己测试的时候看着2.txt的行数在飞涨,会更加直观!

在这里插入图片描述

您可能感兴趣的文章:
阅读全文