nodejs的fs模块学习

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)
  }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,711评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,932评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,770评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,799评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,697评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,069评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,535评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,200评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,353评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,290评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,331评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,020评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,610评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,694评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,927评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,330评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,904评论 2 341

推荐阅读更多精彩内容