Nodejs fs 模块

2018年06月18日 08:02 | 1353次浏览

一、课程介绍

1.1 课程内容

出于安全考虑,浏览器端的JavaScript代码一般无法访问本地文件系统。但对于运行在服务器端的Node.js来说,文件系统是可以直接访问的,Node.js中,fs模块可以对系统文件及目录进行读写操作。

本次课程将带你探索fs模块。


1.2 课程知识点

fs模块的常见操作

同步和异步的区别及适用场景


1.3 课程环境

Xfce终端

Node.js v4.2.1

gedit/vim:文本编辑



二、课程步骤

2.1 同步和异步

不同于C++、Java等编程语言,JavaScript语句是异步执行的,Node.js也是如此。异步使得Node.js能够"同时"处理多个请求,提高了服务程序的并发性。异步特性也是Node.js得以流行的原因之一。


fs模块中所有方法都有同步和异步两种形式,我们可以在学习fs模块本身的同时体会异步和同步的差别。


异步方法中回调函数的第一个参数总是留给异常参数(exception),如果方法成功完成,那么这个参数为null或者undefined。

异步方法实例代码:

var fs = require('fs'); // 载入fs模块

fs.unlink('/tmp/vxzsk', function(err) {
    if (err) {
        throw err;
    }
    console.log('成功删除了 /tmp/vxzsk');
});

同步方法实例代码:

var fs = require('fs');

fs.unlinkSync('/tmp/vxzsk'); // 函数名最后的Sync 表示是同步方法
console.log('成功删除了 /tmp/vxzsk');

同步方法执行完并返回结果后,才能执行后续的代码。而异步方法采用回调函数接收返回结果,可以立即执行后续的代码。

2.2readFile读取文件

使用fs.readFile(filename, [options], callback)方法读取文件。

readFile接收三个参数,filename是文件名;[options]是可选的参数,为一个对象,用于指定文件编码(encoding)及操作方式(flag);callback是回调函数。

在服务器目录(/home/vxzsk)下新建一个文件text.txt,文件中的内容如下:

line one
line two

使用readFile读取此文件,在服务器目录(/home/vxzsk)下新建文件readfile.js,输入如下代码并保存:

var fs = require('fs'); // 引入fs模块

fs.readFile('./text.txt', function(err, data) {
    // 读取文件失败/错误
    if (err) {
        throw err;
    }
    // 读取文件成功
    console.log(data);
});

readFile的回调函数接收两个参数,err是读取文件出错时触发的错误对象,data是从文件读取的数据。

运行程序

$ node readfile.js

会看到输出的内容类似于这样

<Buffer 6c 69 6e 65 20 6f 6e 65 0a 6c 69 6e 65 20 74 77 6f 0a>

这是原始二进制数据在缓冲区中的内容。要显示文件内容可以使用toString()或者设置输出编码,readFile.js可以改成这样:

var fs = require('fs'); // 引入fs模块

// 使用toString()
fs.readFile('./test.txt', function(err, data) {
    // 读取文件失败/错误
    if (err) {
        throw err;
    }
    // 读取文件成功
    console.log('toString: ', data.toString());
});

// 设置编码格式
fs.readFile('./test.txt', 'utf-8', function(err, data) {
    // 读取文件失败/错误
    if (err) {
        throw err;
    }
    // 读取文件成功
    console.log('utf-8: ', data.toString());
});

这样再运行程序就能正常显示出文件中的内容了。

fs.readFileSync(filename, [options])是readFile的同步方法。


2.3 writeFile写入文件

使用fs.writeFile(filename, data, [options], callback)写入内容到文件。

writeFile接收四个参数,filename是文件名称;data是要写入文件的数据;[options]是一个对象为可选参数,包含编码格式(encoding),模式(mode)以及操作方式(flag);callback是回调函数。

nodejs

在服务器(/home/vxzsk)目录下新建writeFile.js文件,输入如下代码并保存:

var fs = require('fs'); // 引入fs模块

// 写入文件内容(如果文件不存在会创建一个文件)
// 写入时会先清空文件
fs.writeFile('./test2.txt', 'test test', function(err) {
    if (err) {
        throw err;
    }

    console.log('Saved.');

    // 写入成功后读取测试
    fs.readFile('./test2.txt', 'utf-8', function(err, data) {
        if (err) {
            throw err;
        }
        console.log(data);
    });
});

运行程序:

$ node writeFile.js

如果要追加数据到文件,可以传递一个flag参数,修改代码为如下所示:

var fs = require('fs'); // 引入fs模块

// 写入文件内容(如果文件不存在会创建一个文件)
// 传递了追加参数 { 'flag': 'a' } 
fs.writeFile('./test2.txt', 'test test', { 'flag': 'a' }, function(err) {
    if (err) {
        throw err;
    }

    console.log('Saved.');

    // 写入成功后读取测试
    fs.readFile('./test2.txt', 'utf-8', function(err, data) {
        if (err) {
            throw err;
        }
        console.log(data);
    });
});

运行程序

$ node writeFile.js

flag传递的值,r代表读取(read)文件,,w代表写入(write)文件,a代表追加(append)写入文件,还有其他的值不作详细介绍。


2.4 使用fs.read和fs.write读写文件

使用fs.read和fs.write读写文件需要使用fs.open打开文件和fs.close关闭文件。


2.4.1 fs.read()

先介绍fs.open(path, flags, [mode], callback)方法,此方法用于打开文件,以便fs.read()读取。path是文件路径,flags是打开文件的方式,[mode]是文件的权限(可选参数,默认值是0666),callback是回调函数。

flags的值:

  • r :读取文件,文件不存在时报错;

  • r+ :读取并写入文件,文件不存在时报错;

  • rs :以同步方式读取文件,文件不存在时报错;

  • rs+ :以同步方式读取并写入文件,文件不存在时报错;

  • w :写入文件,文件不存在则创建,存在则清空;

  • wx :和w一样,但是文件存在时会报错;

  • w+ :读取并写入文件,文件不存在则创建,存在则清空;

  • wx+ :和w+一样,但是文件存在时会报错;

  • a :以追加方式写入文件,文件不存在则创建;

  • ax :和a一样,但是文件存在时会报错;

  • a+ :读取并追加写入文件,文件不存在则创建;

  • ax+ :和a+一样,但是文件存在时会报错。

fs.close(fd, [callback])用于关闭文件,fd是所打开文件的文件描述符。

fs.read(fd, buffer, offset, length, position, callback)方法接收6个参数。

  • fd是文件描述符,必须接收fs.open()方法中的回调函数返回的第二个参数;

  • buffer是存放读取到的数据的Buffer对象;

  • offset指定向buffer中存放数据的起始位置;

  • length指定读取文件中数据的字节数;

  • position指定在文件中读取文件内容的起始位置;

  • callback是回调函数,回调函数的参数:

    • err用于抛出异常;

    • bytesRead是从文件中读取内容的实际字节数;

    • buffer是被读取的缓存区对象。

在服务器(/home/vxzsk)目录中新建文件testread.txt在文件中随意输入一些内容,然后新建read.js文件,输入如下代码并保存:

var fs = require('fs'); // 引入fs模块

// 打开文件
fs.open('./testread.txt', 'r', function(err, fd) {
    if (err) {
        throw err;
    }
    console.log('open file success.');
    var buffer = new Buffer(255);
    // 读取文件
    fs.read(fd, buffer, 0, 10, 0, function(err, bytesRead, buffer) {
        if (err) {
            throw err;
        }
        // 打印出buffer中存入的数据
        console.log(bytesRead, buffer.slice(0, bytesRead).toString());

        // 关闭文件
        fs.close(fd);
    });
});

运行程序:

$ node read.js


2.4.2 fs.write()

fs.write(fd, buffer, offset, length, position, callback)方法的参数和fs.read()相同,buffer是需要写入文件的内容。

在服务器(/home/vxzsk)目录中新建文件testwrite.txt,然后新建write.js文件,输入如下代码并保存:

var fs = require('fs'); // 引入fs模块

// 打开文件
fs.open('./testwrite.txt', `w`, function(err, fd) {
    if (err) {
        throw err;
    }
    console.log('open file success.');
    var buffer = new Buffer('vxzsk');
    // 读取文件
    fs.write(fd, buffer, 0, 6, 0, function(err, written, buffer) {
        if (err) {
            throw err;
        }

        console.log('write success.');

        // 打印出buffer中存入的数据
        var byteLength = buffer.byteLength;
        console.log(byteLength, buffer.slice(0, byteLength).toString());

        // 关闭文件
        fs.close(fd);
    });
});

运行程序

$ node write.js


2.5 目录操作

2.5.1 创建目录

使用fs.mkdir(path, [mode], callback)创建目录,path是需要创建的目录,[mode]是目录的权限(默认值是0777),callback 是回调函数。


在服务器(/home/vxzsk)目录下创建mkdir.js文件,输入如下代码并保存:

var fs = require('fs'); // 引入fs模块

// 创建 newdir 目录
fs.mkdir('./newdir', function(err) {
    if (err) {
        throw err;
    }
    console.log('make dir success.');
});

运行代码

$ node mkdir.js

运行程序后会发现在当前目录下已经创建了newdir目录,删除目录可以使用fs.rmdir(path, callback),但是只能删除空目录。


2.5.2 读取目录

使用fs.readdir(path, callback)读取文件目录。

在服务器(/home/vxzsk)目录下新建readdir.js文件,输入如下代码并保存:

var fs = require('fs'); // 引入fs模块

fs.readdir('./newdir', function(err, files) {
    if (err) {
        throw err;
    }
    // files是一个数组
    // 每个元素是此目录下的文件或文件夹的名称
    console.log(files);
});

运行代码

$ node readdir.js


2.6 结束

fs模块中还有很多其他方法,其使用与前面介绍的方法类似,在此不一一介绍,可自行查阅官方API文档。


三、课程总结

1 和浏览器端JavaScript不同,Node.js可以访问本地文件系统。

2 fs模块用于文件访问,有同步(函数名最后有sync)和异步(函数名后无sync)两种方式。

3 fs模块提供了丰富的api,没必要提前将它们记住,在需要使用时查阅文档即可。



小说《我是全球混乱的源头》

感觉本站内容不错,读后有收获?小额赞助,鼓励网站分享出更好的教程