Node的file模块

算是用NodeJS操作File的一个练手。Demo: https://github.com/lucyhao/demo-express-file
后来看了一些别人的文章,发现自己的这个很单薄,还找了一个别人的图,感觉很好的列出来fs模块的API

node fs api

读文件内容

1
2
3
4
5
6
7
8
9
10
11
12
13
const fs = require('fs'); //引入fs模块
//filePath -> files文件的路径
let rstream = fs.createReadStream(filePath, 'utf8');
//rstream是一个可读流


//异步
fs.readFile(filePath, 'utf8',function(err, data){
//data 是一个buffer数据,读出来的文件内容会在内存中,所以对于大文件,不适合用这个方法
})

//同步
let file = fs.readFileSync(filePath)

stream 与 buffer 的区别在于, buffer会把内容缓存在内存中,内存的大小是有限的,所以对于很大的文件,要注意有可能会导致内存放不下的情况。这个时候就要考虑用stream流的方式。结合网络请求,可以用pipe管道的方式,把读到的数据直接pipe给response。如果说用buffer,是先把内容读入到内存中,然后再发送给client。那么stream就是“数据流”,像“水”一样,从server流向client。

ep:

1
2
3
4
5
6
7
//express router
router.get('/file/:name', function(req, res){

let rstream = fs.createReadStream(name, 'utf8');
rstream.pipe(res);

})

写文件内容

1
2
3
4
5
6
7
8
9
10
11
let wstream = fs.createWriteStream(filePath, 'utf8');
//wstream 是一个可写流

//异步
fs.writeFile(filePath, 'data', (err) => {
if (err) throw err;
console.log('The file has been saved!');
});

//同步
let file = fs.writeFileSync(filePath)

用stream创建的可写流,可以与ReadStream一起使用,可读流.pipe(可写流)。writeStream也可以用write()写内容,然后用end()结束。

ep:

1
2
3
let rstream = fs.createReadStream(filePath, 'utf8');
let wstream = fs.createWriteStream(filePath, 'utf8');
rstream.pipe(wstream);
1
2
3
let wstream = fs.createWriteStream(filePath, 'utf8');
wstream.write(data);
wstream.end();

读文件夹

确切说是读文件夹下面的文件名称. files是文件夹路径下面的文件的名称的array, 不包括’.’和’..’。 同样也是有同步的fs.readdirSync的方法

1
2
3
4
5
6
7
8
//filesDir -> files文件夹的路径
fs.readdir(filesDir, (err, files) => {

files.forEach(file => {
// file name
});

})

删除文件

1
2
3
fs.unlink(filePath, (err) => {
if (err) throw err;
});

创建文件夹

1
2
3
4
5
6
//异步
fs.mkdir(filesDir, function(err){

})
//同步
fs.mkdirSync(filesDir);

当然所有的接口都可以在Node的API文档里面查到,关于fs模块,最应该搞清楚应该就是stream这种数据流了。
用一张别人的图原文。列举了Node的哪些module是stream的。

node module的stream流模块

HTTP reponses & HTTP request都是stream的。突然就跟之前的文章有了联系Node的http处理过程

所以在express中,如果不用中间价,接到的request的data就是stream。我们处理它们的时候,就要使用到事件。
所有的stream都是EventEmitter(还没学习,简单理解就是stream都有很多事件来处理)的实例。

一个例子,处理http request,把数据写到文件中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//express router
router.put('/file/:name', function(req, res){

let body = '';
req.on('data', function (chunk) {
body += chunk; //stream的数据是一块chunk一块chunk的
});
req.on('error', function(){
console.log('error');
})
req.on('end', function () {
let wstream = fs.createWriteStream(filepath, 'utf8');
wstream.write(body);
wstream.end();
res.json({'success' : 'already updated file'});
});

})