Skip to content

FS模块

基本知识

向军大叔每晚八点在 抖音bilibli 直播

xj-small

node 即然是服务器端环境,所以可以操作服务器文件的读写,这与基于浏览器的 JS 是有区别的。

我们需要使用 node.js 的 fs 模块操作文件和管理目录。

同步操作

我们使用 readFileSyncwriteFileSync 对文件进行同步读写操作

  • 同步操作会阻塞进程
  • 如果是写入文件,可以不设置编码

读取文件

首先创建文件hd.txt,内容如下

houdunren.com 后盾人

然后使用fs模块读取文件,因为readFileSync返回内容为Buffer,所以使用toString转为字符串

import { readFileSync } from 'fs'
const content = readFileSync('./hd.txt')
console.log(content.toString('utf-8'))

也可以指定readFileSync的第二个参数即字符编码,将读取的内容转为字符串

import { readFileSync, writeFileSync } from 'fs'

//不指定编码时返回 Buffer 二进制数据流,可以使用toString()转为字符串
//指定编码后转换为字符串返回
const content = readFileSync('hd.json', 'utf8')
console.log(content)

写入文件

使用 writeFileSync 方法可以写入文件

//同步写入文件
writeFileSync('xj.txt', 'houdunren')

通过设置 flat:a 选项来追加文件内容

writeFileSync('xj.txt', 'houdunren', { flag: 'a' })

异步操作

同步文件操作会阻塞进程,所以使用异步文件操作拥有更好的性能,也是推荐的做法。

回调函数

使用 readFilewriteFile 可以对文件进行异步操作,不阻塞进程拥有更好的性能。

  • Node.js以错误优先为思想,所以回调函数第一个参数为错误信息,没有错误时值为null
import { readFile, writeFile } from 'fs'

readFile('hd.txt', 'utf8', (error, content) => {
  if (error) {
    console.log(error)
  } else {
    console.log(content)
    //异步写入文件
    writeFile('xj.txt', content, (error) => {
      if (error) console.log(error)
      else console.log('文件写入成功')
    })
  }
})
console.log('后盾人提示,因为是异步,所以这行较readFile的回调函数先执行')

Promise

下面使用 Promise 对文件的操作方法进行封装

import { readFile, writeFile } from 'fs'

//获取文件
function fileGetContent(file: string): Promise<string> {
  return new Promise((resolve) => {
    readFile(file, 'utf8', (error, content) => {
      resolve(content)
    })
  })
}

//写入文件
function filePutContent(file: string, content: string) {
  return new Promise((resolve) => {
    writeFile(file, content, (error) => {
      if (error) throw error
      resolve(true)
    })
  })
}

// 使用 async/await 使用代码更清晰
async function hd() {
  const content = await fileGetContent('hd.txt')

  await filePutContent('xj.txt', content)
  console.log('xj.txt 写入成功')
}

hd()
console.log('先输出...')

fs/promises

其实我们不需要自己封装,因为 Node 提供了 Promise 操作机制

fs/promises 提供了 Promise 操作机制

import { readFile } from 'fs/promises'

readFile('hd.txt', 'utf-8').then((content) => {
  console.log(content)
}).catch(error=>console.log(error))

文件信息

existsSync

使用 existsSync 判断文件或目录是否存在,返回值是 boolean

import { existsSync } from 'fs'

if (existsSync('hd.txt')) {
  console.log('文件存在')
}

stat

使用 stat 可以获取文件或目录详细信息,比如可用来判断是否是文件或目录。

import { stat } from 'fs'

stat('hda', (error, stats) => {
  if (error) throw new Error('文件不存在或没有操作权限')
  if (stats.isFile()) {
    console.log('这是文件')
  }
  if (stats.isDirectory()) {
    console.log('这是目录')
  }
})

fs/promises 提供了 Promise 的操作方法

import { stat } from 'fs/promises'

//是否是目录
async function fileType(file: string) {
  try {
    const stats = await stat(file)
    return stats.isDirectory() ? 'dir' : 'file'
  } catch (error) {
    if (error) throw new Error('文件不存在或没有操作权限')
  }
}

fileType('hd').then((type) => {
  console.log(type === 'dir' ? '目录' : '文件')
})

使用 unlink 执行异步删除文件

import { unlink, writeFileSync } from 'fs'
writeFileSync('hd.txt', 'houdunren')
setTimeout(() => {
	//三秒后删除文件
  unlink('hd.txt', (error) => {
    if (error) throw error
    console.log('文件删除成功')
  })
}, 3000)

fs/promises 中封装了 Promise 删除文件方法

import { writeFileSync } from 'fs'
import { unlink } from 'fs/promises'

async function hd() {
  await unlink('hd.txt')
}

writeFileSync('hd.txt', 'houdunren.com')
setTimeout(() => {
  hd()
}, 3000)

目录管理

下面向军大叔教大家使用 Node 操作目录

创建目录

下面是使用 mkdirSync 以同步的方式创建多级目录

import { mkdirSync } from 'fs'

const state = mkdirSync('a/b/c/d', { recursive: true })
if (state) {
  console.log('目录创建成功')
}

使用 mkdir 可以创建目录,如果目录已经存在将报错

import { mkdir } from 'fs'

mkdir('hd', (error) => {
  if (error) throw error
  console.log('目录创建成功')
})

fs/promises 提供了 Promise 操作方法

import { mkdir } from 'fs/promises'

async function hd() {
  await mkdir('hd')
}

hd()

删除目录

使用 rmdirSync 以同步的方式删除多级目录,同步删除会阻塞代码,建议尽可能使用异步操作。

import { rmdirSync } from 'fs'

rmdirSync('a', { recursive: true })

使用 rmdir 异步删除目录,默认只能删除空目录

import { rmdir } from 'fs'

rmdir('hd', (error) => {
  if (error) throw error
  console.log('目录删除成功')
})

递归删除目录,即删除目录中的所有内容,可以删除非空目录

import { rmdir } from 'fs'

rmdir('hd', { recursive: true }, (error) => {
  if (error) throw error
  console.log('目录删除成功')
})

fs/promises 提供了 Promise 操作方法,用于异步删除目录

import { rmdir } from 'fs/promises'

rmdir('hd')
  .then((e) => console.log('删除成功'))
  .catch((error) => console.log('删除失败'))

下面是递归删除目录,非空目录也可以一次删除

import { rmdir } from 'fs'

rmdir('hd', { recursive: true }, (error) => {
  if (error) throw error
  console.log('目录删除成功')
})