fs 模塊常用api方法
// 讀取文件
- readFile(),readFileSync()
// 寫入文件
- writeFile(),writeFileSync()
// 判斷文件夾是否存在
- exists(path, callback)
// 創(chuàng)建文件夾
- mkdir()
// 讀取文件夾內(nèi)所有文件
- readdir(),readdirSync()
// 判斷文件狀態(tài)(是文件還是文件夾)
- stat()
// 監(jiān)聽文件變化
- watchfile(),unwatchfile()
// 創(chuàng)建讀取文件流
- createReadStream()
// 創(chuàng)建寫入文件流
- createWriteStream()
1.readFile,readFileSync
異步讀取文件
fs.readFile('./test.txt', function(err, buffer) {
if (err) throw err
process(buffer)
})
readFile 第一個參數(shù)是文件路徑,可以是絕對路徑或者相對路徑,如果是相對路徑,則相對于當(dāng)前命令行目錄(相當(dāng)于process.cwd())
同步讀取文件
var text = fs.readFileSync(fileName, 'utf8')
// 將文件按行拆成數(shù)組
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!")
})
第一個參數(shù)是文件名,第二個參數(shù)是寫入內(nèi)容,第三個參數(shù)是回調(diào)方法
回調(diào)函數(shù)前面,還可以再加一個參數(shù),表示寫入字符串的編碼(默認是 utf8)。
fs.writeFile('message.txt', 'Hello Node.js', 'utf8', callback)
同步寫入文件
fs.writeFileSync(fileName, str, 'utf8')
writeFileSync方法用于同步寫入文件。它的第一個參數(shù)是文件路徑,第二個參數(shù)是寫入文件的字符串,第三個參數(shù)是文件編碼,默認為 utf8。
exists(path, callback)
exists 方法用來判斷給定路徑是否存在,然后不管結(jié)果如何,都會調(diào)用回調(diào)函數(shù)。
fs.exists('/path/to/file', function(exists) {
util.debug(exists ? "it's there" : 'no file!')
})
existsSync表示同步判斷給定路徑是否存在
下面的例子是如果給定目錄存在,就刪除它。
// 判斷當(dāng)前目錄是否存在,如果存在就刪除
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 方法是異步操作,所以必須小心,不要同時發(fā)起多個 readFile 請求。
for (var i = 1; i <= 1000; i++) {
fs.readFile('./' + i + '.txt', function() {
// do something with the file
})
}
上面代碼會同時發(fā)起 1000 個 readFile 異步請求,很快就會耗盡系統(tǒng)資源。
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)
由于同步操作文件會阻塞進程,一般對于流量比較大的網(wǎng)站,不建議同步操作
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 方法的參數(shù)是一個文件或目錄,它產(chǎn)生一個對象,該對象包含了該文件或目錄的具體信息。
我們往往通過該方法判斷是文件還是目錄。
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方法監(jiān)聽一個文件,如果該文件發(fā)生變化,就會自動觸發(fā)回調(diào)函數(shù)。
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方法用于解除對文件的監(jiān)聽。
createReadStream
createReadStream方法往往用于打開大型的文本文件,創(chuàng)建一個讀取操作的數(shù)據(jù)流。每次發(fā)送會觸發(fā)一個 data 事件,發(fā)送結(jié)束會觸發(fā) 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方法創(chuàng)建一個寫入數(shù)據(jù)流對象,該對象的write方法用于寫入數(shù)據(jù),end方法用于結(jié)束寫入操作。
var writeStream = fs.createWriteStream(fileName, {
encoding: 'utf8'
})
writeStream.write(str)
writeStream.end()
createWriteStream方法和createReadStream方法配合,可以實現(xiàn)拷貝大型文件。
function fileCopy(filename1, filename2, done) {
var readStream = fs.createReadStream(filename1)
var writeStream = fs.createWriteStream(filename2)
readStream.pipe(writeStream)
}
常用 fs 模塊操作
// 引入mkdirp模塊用來創(chuàng)建文件夾
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) {
// 獲取當(dāng)前目錄的所有文件
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對應(yīng)文件
stats(srcDir, targetDir)
})
}
// 創(chuàng)建文件夾
function createProjectFolder(projectPath) {
const exists = fs.existsSync(projectPath)
if (!exists) {
mkdirp.sync(projectPath)
}
}
// 判斷當(dāng)前路徑是文件還是文件夾,是文件夾就拷貝文件夾,是文件就拷貝文件
async function stats(srcDir, targetDir) {
let stats = await util.promisify(fs.stat)(srcDir)
let isFile = stats.isFile()
let isDir = stats.isDirectory()
if (isFile) {
// 如果是文件,直接copy對應(yīng)文件
copyFile(srcDir, targetDir)
} else if (isDir) {
// 如果是文件夾,先創(chuàng)建目標文件夾,再執(zhí)行copyFolder方法
createProjectFolder(targetDir)
copyFolder(srcDir, targetDir)
}
}