Nodejs file and stream

简介:

先来个题外话,听闻express的作者TJ大神已投入到Go的怀抱啦!真是遗憾啊,感谢大神对NodeJS社区的贡献.

File

文件操作对于一般的后端语言来说,是非常基础的功能,今天来说说NodeJS里的文件API,详情API地址可以看这里,官方文件API,本篇只说一些常用的方法


首先文件api在NodeJS里是唯一的一个具有同步和异步的方法调用,所有的文件相关的方法都在file模块内,这个是系统内置模块,请求方法如下

var fs = require('file');

接下来就可以测试文件API啦,先来一个常用的readFile方法

fs.readFile(filename, [options], callback)

说到读文件,这里就要先讲讲NodeJS的路径问题

  • __dirname 程序目录
  • process.cwd() 代表程序当前工作目录
  • . 相对于程序路径的上级
  • .. 相对于程序路径的上上级

比如这里获取当前运行文件同级目录里的feenan.js,代码如下

fs.readFile(__dirname + '/feenan.js', 'utf8', function(err, data){
    // do stuff here    
    if(!err){
        console.log(data);
    }
})

方法的第二个参数可以传递数据编码格式,这里设置utf8,最后一个参数是一个回调,当文件读取完毕的时候会调用,出错的话,err参数有值,否则为null,这时就可以对数据进行处理了.

这个方法对应的同步方法是readFileSync,一般同步方法就是在后面加上Sync

目前这个读取文件的方案,对于小文件还可以接受,但是大文件的话,则性能不是很好,因为这是一次性的分配文件内容大小的内存的,后面会讲到以流的方式来处理.

说完了读取文件,再来说说读取文件夹

fs.readdir(path, callback)

读取文件夹信息比较简单,传递目录路径,以及回调函数.

fs.readdir(__dirname, function(err, files){
    if(!err){
        files.forEach(function(v){
            console.log(v);
        })
    }
});

上面的主要说是读取当前程序所在目录下面的信息,回调函数的files是一个数组,里面存放目录列表的名字

这里当获取到目录列表的时候,想读取某个文件怎么办?怎么来区分哪个是目录哪个是文件呢?这里得讲下另外一个常用的api

fs.stat(path, callback)

上面的API是读取文件属性,这里的文件包括目录以及单个文件,直接来看个例子吧,对上面返回的文件数组进行过滤然后分别显示哪些是目录,哪些是文件

function file(i){
    var filename = files[i];
    fs.stat(__dirname + '/' + filename, function(err, stat){
        // 保存文件属性对象
        stats[i] = stat;
        if(err){
            console.log('file read error!');
        }else{
            if(stat.isDirectory()){
                console.log('目录名: ' + filename);
            }else{
                console.log('文件名: ' + filename);
            }
            i++;
            if(i === files.length){
                done();
            }else{
                file(i);
            }
        }
    });
}
file(0);

上面主要是用到了fs.stat返回的stat.isDirectory方法来检查是否是文件夹

最后贴一个完整的获取目录下的文件信息,并支持命令行输入索引来查看文件信息

var fs = require('fs');
var stdin = process.stdin,
    stdout = process.stdout;

// 异步调用获取当前工作目录下的列表
fs.readdir(__dirname, function(err, files){
    // 列出文件列表之后,提示输入想查看的内容
    var done = function(){
        console.log('');
        stdout.write('输入你的选择: ');
        stdin.resume();
        stdin.setEncoding('utf8');
        stdin.on('data', function(data){
            if(!files[+data]){
                stdout.write('输入你的选择: ');
            }else{
                stdin.pause();
                // 开始读取选择的文件夹或者文件
                var filename = files[+data];
                if(stats[+data].isDirectory()){
                    // 开始读取文件夹里的内容
                    fs.readdir(__dirname + '/' + filename, function(err, files){
                        if(!err){
                            console.log('');
                            console.log('(' + files.length  + '个文件' + ')');
                            files.forEach(function(v){
                                console.log('      -' + v);
                            })
                            console.log('');
                        }
                    });
                }else{
                    // 开始读取文件
                    fs.readFile(__dirname + '/' + filename, 'utf8',  function(err, data){
                        console.log('');
                        console.log(data.replace(/(.*)g/, '    $1'));
                    });
                }
            }
        });
    }
    var stats = [];
    if(!files.length){
        console.log('不存在任何文件列表!');
        return;
    }
    console.log('列出你想看的列表内容: ');
    function file(i){
        var filename = files[i];
        fs.stat(__dirname + '/' + filename, function(err, stat){
            // 保存文件属性对象
            stats[i] = stat;
            if(err){
                console.log('file read error!');
            }else{
                if(stat.isDirectory()){
                    console.log('目录名: ' + filename);
                }else{
                    console.log('文件名: ' + filename);
                }
                i++;
                if(i === files.length){
                    done();
                }else{
                    file(i);
                }
            }
        });
    }
    file(0);
});

Stream

刚才上面讲到了读取文件时的一个影响性能的地方,这里可以用流来处理,看看代码

var readstream = fs.createReadStream(__dirname + '/demo.js', { Encoding: 'utf8'});
var content = [];

readstream.on('data', function(data){
    content.push(data);
})

readstream.on('end', function(data){
    content.push(data);
    console.log(content.join(''));
})

上面用到了文件流里的createReadStream方法,参数如下

fs.createReadStream(path, [options])

选项里可以传入文件编码信息,更多参数可以参考官网API

然后这里的只读流对象提供了读取数据以及数据完成事件,这种方式跟上面的一次性读取内容的区别在于,内存是一块一块分配的,而不是一次性分配很大的内存,这种情况用在网络请求文件的时候,性能尤其明显

下面再来一个可写流,方法参数如下

fs.createWriteStream(path, [options])

var writestream = fs.createWriteStream(__dirname + '/demo.js', { Encoding: 'utf8'});
writestream.write('hello feenan!');

而且有一个方便的方法可以从只读流写入到可写流中,效率也是最好的

var readstream = fs.createReadStream(__dirname + '/demo.js', { Encoding: 'utf8'});
var writestream = fs.createWriteStream(__dirname + '/demo.js', { Encoding: 'utf8'});
readstream.pipe(writestream);

其实就是调用了流的pipe管道方法,确实人如其名:)

总结

文件与流都是file模块下面的API,用好这些方法,对构建前端自动化,编写网络服务程序都有很好的帮助!


目录
相关文章
|
3月前
|
JavaScript 大数据 数据处理
什么是Node.js的流(stream)?它们有什么作用?
什么是Node.js的流(stream)?它们有什么作用?
21 1
|
2月前
|
消息中间件 Web App开发 JavaScript
Node.js【简介、安装、运行 Node.js 脚本、事件循环、ES6 作业队列、Buffer(缓冲区)、Stream(流)】(一)-全面详解(学习总结---从入门到深化)
Node.js【简介、安装、运行 Node.js 脚本、事件循环、ES6 作业队列、Buffer(缓冲区)、Stream(流)】(一)-全面详解(学习总结---从入门到深化)
70 0
|
3月前
|
JavaScript 前端开发 API
Node.js【简介、安装、运行 Node.js 脚本、事件循环、ES6 作业队列、Buffer(缓冲区)、Stream(流)】(一)-全面详解(学习总结---从入门到深化)(下)
Node.js【简介、安装、运行 Node.js 脚本、事件循环、ES6 作业队列、Buffer(缓冲区)、Stream(流)】(一)-全面详解(学习总结---从入门到深化)
33 0
|
3月前
|
消息中间件 Web App开发 JavaScript
Node.js【简介、安装、运行 Node.js 脚本、事件循环、ES6 作业队列、Buffer(缓冲区)、Stream(流)】(一)-全面详解(学习总结---从入门到深化)(上)
Node.js【简介、安装、运行 Node.js 脚本、事件循环、ES6 作业队列、Buffer(缓冲区)、Stream(流)】(一)-全面详解(学习总结---从入门到深化)
42 0
|
4天前
|
JavaScript 算法 网络协议
【Node系列】node中的流(Stream)
Node.js 中的流(Stream)是一种处理数据的方式,它允许你以流的方式处理数据,而不是一次性加载整个数据集。这种方式对于处理大量数据非常有用,因为它可以减少内存的使用并提高性能。
17 4
|
3月前
|
JavaScript 大数据 数据处理
什么是Node.js的流(stream)?它们有什么作用?
什么是Node.js的流(stream)?它们有什么作用?
57 3
|
3月前
|
存储 JavaScript 网络协议
什么是Node.js Stream(流)?
什么是Node.js Stream(流)?
51 0
|
6月前
|
JavaScript API
使用 Node.js Stream API 减少服务器端内存消耗的一个具体例子
使用 Node.js Stream API 减少服务器端内存消耗的一个具体例子
58 0
|
6月前
|
JavaScript 网络协议 前端开发
关于 Node.js Stream API 的用法概述
关于 Node.js Stream API 的用法概述
30 0
|
10月前
|
存储 运维 JavaScript
【Node.js实战】一文带你开发博客项目之日志(文件读写、stream流、写日志)
【Node.js实战】一文带你开发博客项目之日志(文件读写、stream流、写日志)
167 3