fs是filesystem的缩写,基本上就是node对于文件系统操作封装的一些api
一、文件的读写
文件的读写这里面的api有readFile(),writeFile(),和readFileSync(),writeFileSync()。前者是异步,后者是同步,两种不同的情况供开发者选择。
readFile()和readFileSync()
readFile用于异步读取数据,他有几个参数:
参数 | 是否必须 | 例子 | 作用 |
---|---|---|---|
文件的路径 | 是 | './image.png' | 可以是绝对路径,也可是相对路径,如果是相对路径,是相对于当前进程所在的路径 process.cwd(),官方文档上好像写也可以传一个buffer......还能是文件名和文件描述符(不知道是什么东西) |
options配置 | 否 | 'utf-8' | 可以配置文件编码实例,默认是utf-8 |
读取完成后的回调参数 | 是 | func (err, buffer) { } | 该函数一参是发生错误时的错误对象,二参是代表文件内容的buffer实例 |
如果,文件的路径是一个目录,会返回一个错误......freeBSD不会,好像基于平台.....
同步的方法readFileSync()和这个一样,使用的例子如下
const text = fs.readFile('etc/passws', 'utf-8' (error, buffer) => {
if(error) throw err
console.log(buffer)
}) {
}
//将文件按行拆成数组......
text.split(/\r?\n/).forEach((item) => {
console.log(item)
})
writeFile()和writeFileSync()
用于写入文件。
参数 | 是否必须 | 例子 | 作用 |
---|---|---|---|
文件路径 | 是 | 上同 | 上同 |
写入的字符串或文件 | 是 | 'hello’ | 可以是字符串,也可以是文件名,还可以是buffer |
option配置 | 否 | 上同 | 上同 |
写入完成时的回调 | 是 | 上同 | 上同 |
fs.writeFile('message.txt', 'Hello Node.js', (err) => {
if (err) throw err;
console.log('The file has been saved!');
});
这里的官方文档上写了注意......多次对同一文件使用,而且不等待回调函数,是不安全的,对于多次写入同一文件,强烈建议使用fs.createWriteStream
fs.createWriteStream()
这个方法,创建了一个写入数据流的对象,该对象的write方法用于写入数据,end方法用于结束写入操作.....
const out = fs.createWriteStream(fileName, {
flags: 'w',
encoding: 'utf8',
fd: null,
mode: 0o666,
autoClose: true
})
out.write(str)
out.end()
参数 | 是否必须 | 作用 |
---|---|---|
文件路径 | 是 | 略 |
options | 是 | 一些配置,具体的配置有flags:一个string,大概是写入的模式比如w,r+等,encoding:编码;fd;mode;autoClose:设置是否自动关闭;start:一个integer |
注意: 如果autoClose设置为true(默认),则在遇到error和end的时候,会自动关闭,如果是false,即使有错误,也不会被关闭,所以要注意了,你要正确的负责关闭。,并确保文件描述符没有泄露, fd和mode暂时还不知道它的作用。
如果要对统一文件进行反复的读写,知道一直不停的out.write()就可以了,最后别忘记end()
相对的createWriteStream和它一样使用,但是它会返回一个ReadStream可读流对象。而且它第二个参数options中对了一个end字段。
fs.createReadStream('sample.txt', { start: 90, end: 99 });
// 设置了start和end之后,使其可以从文件读取一定范围的字节而不是整个文件
createWriteStream和createReadSteam结合使用拷贝大文件实例
const fileCopy = (filename1, filename2, done) => {
let input = fs.createReadStream(filename1);
let output = fs.createWriteStream(filename2);
input.on('data', function(d) { output.write(d) })
input.on('error', function(error) { throw error })
input.on('end', function() {
output.end()
if (done) done();
})
}
二、文件的操作
exist() 、mkdir()
exist()判断文件目录是否存在,他的回调函数参数,是不管最后结果如何都会调用的,需要注意的是,以前我们写java的文件IO,在打开文件的时候都需要先用类似方法判断目录是否存在,但是node里边,open方法本身就能检查,
mkdir()用于新建目录,它接收三个参数,目录名、权限值和回调函数
const fs = require('fs');
// 如果给定目录存在,就删除它。
if(fs.existSync(outputFolder)) {
console.log('删除' + outputFolder)
fs.rmdirSync(outputFolder)
}
// 新建目录
fs.mkdir('./helloDir',0777, function (err) {
if (err) throw err;
});
stat()
它用来判断是一个文件还是一个目录,接收一个文件或者目录。
watch()
参数 | 是否必须 | 作用 |
---|---|---|
文件名 | 是 | 略 |
options参数 | fou | 如果指定,则是一个对象,包括persistet:布尔值(默认true),表明文件被监控时,进程是否还要继续运行; recursive:指明是否全部子目录应该被监视,或只是当前目录(默认false);encoding:默认utf-8 |
监控文件,如果文件发生变化,则触发回调函数。返回的是一个fs.FSWatch
参数 | 是否必须 | 作用 |
---|---|---|
文件名 | 是 | 略 |
options参数 | fou | 如果指定,则是一个对象,包括persistet:布尔值(默认true),表明文件被监控时,进程是否还要继续运行; recursive:指明是否全部子目录应该被监视,或只是当前目录(默认false);encoding:默认utf-8 |
fs.watch('somedir', (eventType, filename) => {
console.log(`事件类型是: ${eventType}`);
if (filename) {
console.log(`提供的文件名: ${filename}`);
} else {
console.log('未提供文件名');
}
});
注意,还有一个watchFile(),作用和它差不多,效率低,官方建议用这个。但fs.watch API 不是 100% 跨平台一致的,且在某些情况下不可用。递归选项只支持 macOS 和 Windows
fs.lstat(path)
接收一个文件url,返回一个fs.Stats实例,他的同步方法是fs.lstatSync(path)
三、webpack应用,写一个多入口的初始化entry函数
在使用开发react应用的时候,使用webpack打包需要有多入口的时候,也就是说,我有多个entry,每个enrty各自生成一个html模版,这个时候,我们可以写个自动脚本,如下
const _ = require('lodash')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const fs = require('fs');
const path = require('path');
const entryDir = path.join(__dirname, 'src/entry/')
const templateFile = path.join(__dirname, 'index.html')
const addEntryFn = (config, key, value) => {
console.log(`找到了entry!,key=${key},value=${value}`);
config.entry[key] = value
config.plugins.push(new HtmlWebpackPlugin(
{
title: key,
filename: key + '.html',
chunks: [key],
template: templateFile,
multihtmlCache: true,
}
))
}
const getEntrys = (config, rootpath, fn) => {
const files = fs.readdirSync(rootpath)
for(let key in files) {
const fullName = path.join(rootpath, "/", files[key])
const stat = fs.lstatSync(fullName)
if (stat.isDirectory()) {
getEntrys(config, fullName, fn)
} else {
const fileName = path.basename(fullName, '.jsx')
if (_.startsWith(fileName, 'entry-')) {
const entryKey = fileName.replace('entry-', '')
fn(config, entryKey, fullName)
}
}
}
}
module.exports = function (config) {
getEntrys(config, entryDir, addEntryFn);
}
网友评论