fs 模块常用api方法
// 读取文件
- readFile(),readFileSync()
// 写入文件
- writeFile(),writeFileSync()
// 判断文件夹是否存在
- exists(path, callback)
// 创建文件夹
- mkdir()
// 读取文件夹内所有文件
- readdir(),readdirSync()
// 判断文件状态(是文件还是文件夹)
- stat()
// 监听文件变化
- watchfile(),unwatchfile()
// 创建读取文件流
- createReadStream()
// 创建写入文件流
- createWriteStream()
1.readFile,readFileSync
异步读取文件
fs.readFile('./test.txt', function(err, buffer) {
if (err) throw err
process(buffer)
})
readFile
第一个参数是文件路径,可以是绝对路径或者相对路径,如果是相对路径,则相对于当前命令行目录(相当于process.cwd()
)
同步读取文件
var text = fs.readFileSync(fileName, 'utf8')
// 将文件按行拆成数组
text.split(/\r?\n/).forEach(function(line) {
// do something
})
writeFile,writeFileSync
异步写入文件
writeFile
方法用于异步写入文件
fs.writeFile('message.txt', 'Hello Node.js', err => {
if (err) throw err
console.log("It's saved!")
})
第一个参数是文件名,第二个参数是写入内容,第三个参数是回调方法
回调函数前面,还可以再加一个参数,表示写入字符串的编码(默认是 utf8)。
fs.writeFile('message.txt', 'Hello Node.js', 'utf8', callback)
同步写入文件
fs.writeFileSync(fileName, str, 'utf8')
writeFileSync
方法用于同步写入文件。它的第一个参数是文件路径,第二个参数是写入文件的字符串,第三个参数是文件编码,默认为 utf8。
exists(path, callback)
exists
方法用来判断给定路径是否存在,然后不管结果如何,都会调用回调函数。
fs.exists('/path/to/file', function(exists) {
util.debug(exists ? "it's there" : 'no file!')
})
existsSync
表示同步判断给定路径是否存在
下面的例子是如果给定目录存在,就删除它。
// 判断当前目录是否存在,如果存在就删除
if (fs.existsSync(outputFolder)) {
console.log('Removing ' + outputFolder)
fs.rmdirSync(outputFolder)
}
mkdir(),writeFile(),readFile()
var fs = require('fs')
// 新建目录
fs.mkdir('./helloDir', 0777, function(err) {
if (err) throw err
})
// 写入文件
fs.writeFile('./helloDir/message.txt', 'Hello Node', function(err) {
if (err) throw err
console.log('文件写入成功')
})
// 读取文件
var fs = require('fs')
fs.readFile('./helloDir/message.txt', 'UTF-8', function(err, data) {
if (err) throw err
console.log(data)
})
readFile 方法是异步操作,所以必须小心,不要同时发起多个 readFile 请求。
for (var i = 1; i <= 1000; i++) {
fs.readFile('./' + i + '.txt', function() {
// do something with the file
})
}
上面代码会同时发起 1000 个 readFile 异步请求,很快就会耗尽系统资源。
mkdirSync(),writeFileSync(),readFileSync()
这三个方法是建立目录、写入文件、读取文件的同步版本。
fs.mkdirSync('./helloDirSync', 0777)
fs.writeFileSync('./helloDirSync/message.txt', 'Hello Node')
var data = fs.readFileSync('./helloDirSync/message.txt', 'UTF-8')
console.log('file created with contents:')
console.log(data)
由于同步操作文件会阻塞进程,一般对于流量比较大的网站,不建议同步操作
readdir,readdirSync
readdir
方法用于读取目录
fs.readdir(process.cwd(), function(err, files) {
if (err) {
console.log(err)
return
}
var count = files.length
var results = {}
files.forEach(function(filename) {
fs.readFile(filename, function(data) {
results[filename] = data
count--
if (count <= 0) {
// 对所有文件进行处理
}
})
})
})
stat()
stat 方法的参数是一个文件或目录,它产生一个对象,该对象包含了该文件或目录的具体信息。
我们往往通过该方法判断是文件还是目录。
var fs = require('fs')
fs.readdir('/etc/', function(err, files) {
if (err) throw err
files.forEach(function(file) {
fs.stat('/etc/' + file, function(err, stats) {
if (err) throw err
if (stats.isFile()) {
console.log('%s is file', file)
} else if (stats.isDirectory()) {
console.log('%s is a directory', file)
}
console.log('stats: %s', JSON.stringify(stats))
})
})
})
watchfile(),unwatchfile()
watchfile
方法监听一个文件,如果该文件发生变化,就会自动触发回调函数。
var fs = require('fs')
fs.watchFile('./testFile.txt', function(curr, prev) {
console.log('the current mtime is: ' + curr.mtime)
console.log('the previous mtime was: ' + prev.mtime)
})
fs.writeFile('./testFile.txt', 'changed', function(err) {
if (err) throw err
console.log('file write complete')
})
unwatchfile
方法用于解除对文件的监听。
createReadStream
createReadStream
方法往往用于打开大型的文本文件,创建一个读取操作的数据流。每次发送会触发一个 data 事件,发送结束会触发 end 事件。
var fs = require('fs')
function readLines(input, func) {
var remaining = ''
input.on('data', function(data) {
remaining += data
})
input.on('end', function() {
if (remaining.length > 0) {
doSomething(remaining)
}
})
}
function doSomething(data) {
console.log('Line: ' + data)
}
var input = fs.createReadStream('lines.txt')
readLines(input, func)
createWriteStream()
createWriteStream
方法创建一个写入数据流对象,该对象的write
方法用于写入数据,end
方法用于结束写入操作。
var writeStream = fs.createWriteStream(fileName, {
encoding: 'utf8'
})
writeStream.write(str)
writeStream.end()
createWriteStream
方法和createReadStream
方法配合,可以实现拷贝大型文件。
function fileCopy(filename1, filename2, done) {
var readStream = fs.createReadStream(filename1)
var writeStream = fs.createWriteStream(filename2)
readStream.pipe(writeStream)
}
常用 fs 模块操作
// 引入mkdirp模块用来创建文件夹
const mkdirp = require('mkdirp')
// 引入对于nodejs模块
const path = require('path')
const fs = require('fs')
const util = require('util')
// 拷贝文件
function copyFile(srcPath, targetPath) {
var readstream = fs.createReadStream(srcPath)
var writestream = fs.createWriteStream(targetPath)
readstream.pipe(writestream)
}
// 拷贝文件夹
async function copyFolder(templatePath, projectPath) {
// 获取当前目录的所有文件
let files = await util.promisify(fs.readdir)(templatePath)
files.forEach(filename => {
// 生成源文件地址
let srcDir = path.join(templatePath, filename)
// 生成copy目标文件地址
let targetDir = path.join(projectPath, filename)
// copy对应文件
stats(srcDir, targetDir)
})
}
// 创建文件夹
function createProjectFolder(projectPath) {
const exists = fs.existsSync(projectPath)
if (!exists) {
mkdirp.sync(projectPath)
}
}
// 判断当前路径是文件还是文件夹,是文件夹就拷贝文件夹,是文件就拷贝文件
async function stats(srcDir, targetDir) {
let stats = await util.promisify(fs.stat)(srcDir)
let isFile = stats.isFile()
let isDir = stats.isDirectory()
if (isFile) {
// 如果是文件,直接copy对应文件
copyFile(srcDir, targetDir)
} else if (isDir) {
// 如果是文件夹,先创建目标文件夹,再执行copyFolder方法
createProjectFolder(targetDir)
copyFolder(srcDir, targetDir)
}
}