程序员scholar 程序员scholar
首页
  • Java 基础

    • JavaSE
    • JavaIO
    • JavaAPI速查
  • Java 高级

    • JUC
    • JVM
    • Java新特性
    • 设计模式
  • Web 开发

    • Servlet
    • Java网络编程
  • Web 标准

    • HTML
    • CSS
    • JavaScript
  • 前端框架

    • Vue2
    • Vue3
    • Vue3 + TS
    • 微信小程序
    • uni-app
  • 工具与库

    • jQuery
    • Ajax
    • Axios
    • Webpack
    • Vuex
    • WebSocket
    • 第三方登录
  • 后端与语言扩展

    • ES6
    • Typescript
    • node.js
  • Element-UI
  • Apache ECharts
  • 数据结构
  • HTTP协议
  • HTTPS协议
  • 计算机网络
  • Linux常用命令
  • Windows常用命令
  • SQL数据库

    • MySQL
    • MySQL速查
  • NoSQL数据库

    • Redis
    • ElasticSearch
  • 数据库

    • MyBatis
    • MyBatis-Plus
  • 消息中间件

    • RabbitMQ
  • 服务器

    • Nginx
  • Spring框架

    • Spring6
    • SpringMVC
    • SpringBoot
    • SpringSecurity
  • SpringCould微服务

    • SpringCloud基础
    • 微服务之DDD架构思想
  • 日常必备

    • 开发常用工具包
    • Hutoll工具包
    • IDEA常用配置
    • 开发笔记
    • 日常记录
    • 项目部署
    • 网站导航
    • 产品学习
    • 英语学习
  • 代码管理

    • Maven
    • Git教程
    • Git小乌龟教程
  • 运维工具

    • Docker
    • Jenkins
    • Kubernetes
  • 算法笔记

    • 算法思想
    • 刷题笔记
  • 面试问题常见

    • 十大经典排序算法
    • 面试常见问题集锦
关于
GitHub (opens new window)
首页
  • Java 基础

    • JavaSE
    • JavaIO
    • JavaAPI速查
  • Java 高级

    • JUC
    • JVM
    • Java新特性
    • 设计模式
  • Web 开发

    • Servlet
    • Java网络编程
  • Web 标准

    • HTML
    • CSS
    • JavaScript
  • 前端框架

    • Vue2
    • Vue3
    • Vue3 + TS
    • 微信小程序
    • uni-app
  • 工具与库

    • jQuery
    • Ajax
    • Axios
    • Webpack
    • Vuex
    • WebSocket
    • 第三方登录
  • 后端与语言扩展

    • ES6
    • Typescript
    • node.js
  • Element-UI
  • Apache ECharts
  • 数据结构
  • HTTP协议
  • HTTPS协议
  • 计算机网络
  • Linux常用命令
  • Windows常用命令
  • SQL数据库

    • MySQL
    • MySQL速查
  • NoSQL数据库

    • Redis
    • ElasticSearch
  • 数据库

    • MyBatis
    • MyBatis-Plus
  • 消息中间件

    • RabbitMQ
  • 服务器

    • Nginx
  • Spring框架

    • Spring6
    • SpringMVC
    • SpringBoot
    • SpringSecurity
  • SpringCould微服务

    • SpringCloud基础
    • 微服务之DDD架构思想
  • 日常必备

    • 开发常用工具包
    • Hutoll工具包
    • IDEA常用配置
    • 开发笔记
    • 日常记录
    • 项目部署
    • 网站导航
    • 产品学习
    • 英语学习
  • 代码管理

    • Maven
    • Git教程
    • Git小乌龟教程
  • 运维工具

    • Docker
    • Jenkins
    • Kubernetes
  • 算法笔记

    • 算法思想
    • 刷题笔记
  • 面试问题常见

    • 十大经典排序算法
    • 面试常见问题集锦
关于
GitHub (opens new window)
npm

(进入注册为作者充电)

  • node.js

    • Node.js 初识
    • 包与 npm 包管理器
    • Buffer 缓冲器
    • fs 文件系统
      • 1. Node 中的 fs 文件系统
      • 2. fs 文件写入
        • 2.1 简单文件写入
        • 2.2 流式文件写入
      • 3. 文件读取
        • 3.1 简单文件读取
        • 3.2 流式文件读取
    • MongoDB 非关系型数据库
  • node.js
  • node.js
scholar
2024-08-02
目录

fs 文件系统

# fs 文件系统

# 1. Node 中的 fs 文件系统

  • 在 Node 中有一个文件系统,所谓的文件系统,就是对计算机中的文件进行增删改查等操作。
  • 在 NodeJs 中,给我们提供了一个模块,叫做fs模块(文件系统),专门用于操作文件。
  • fs模块是 Node 的核心模块,使用的时候,无需下载,直接引入。
    // 引入fs模块
    var fs = require("fs");
    
    1
    2

fs 中的大部分方法都为我们提供了两个版本:

  1. 同步方法:带 sync 的方法
    • 同步方法会阻塞程序的执行
    • 同步方法通过返回值返回结果
  2. 异步方法:不带 sync 的方法
    • 异步方法不会阻塞程序的执行
    • 异步方法都是通过回调函数来返回结果的

[!TIP] Nodejs 的一个特点是异步非阻塞,所以学习的都是异步方法。

# 2. fs 文件写入

文件写入有两种方法,一种是 writeFileSync(同步),另一种是 writeFile(异步的)。

// 同步方法
fs.writeFileSync(file, data[, options])
// 异步方法
fs.writeFile(file, data[, options], callback)
1
2
3
4

# 2.1 简单文件写入

[!TIP] 简单文件写入方式是一种异步操作,事实上,后面讲的都是异步操作。

语法:

fs.writeFile(file, data[, options], callback(err) => {})
1
  • file:要写入的文件路径+文件名+后缀
  • data:要写入的数据
  • options:配置对象(可选参数)
    • encoding:设置文件的编码方式,默认值:utf8(万国码)
    • mode:设置文件的操作权限,默认值是:0o666 = 0o222 + 0o444
      • 0o111:文件可被执行的权限,.exe .msc 几乎不用,linux有自己一套操作方法。
      • 0o222:文件可被写入的权限
      • 0o444:文件可别读取的权限
    • flag:打开文件要执行的操作,默认值是 'w'
      • a:追加
      • w:写入
  • callback:回调函数
    • err:错误对象

举例:

//引入内置的fs模块
let fs = require('fs')

//调用writeFile方法
fs.writeFile(__dirname+'/demo.txt','kobe,123', {mode: 0o666, flag: 'a'}, err => {
    if(err) console.log('文件写入失败', err)
    else console.log('文件写入成功')
})
1
2
3
4
5
6
7
8

[!TIP] 在Node中有这样一个原则:错误优先。所以有了回调:err=>{}。

# 2.2 流式文件写入

流式文件写入适用于一些比较大的文件,可以分多次向文件中写入内容,有效避免内存溢出的问题。

[!TIP] 可以把流式文件写入比作是使用水管从河里往家里运水,流式文件写入首先要创建流(水管),然后要检测流的状态,文件传输完毕,则要关闭流(拿开水管)。

创建一个文件可写流:

fs.createWriteStream(path[, options])
1

参数说明:

  • path:要写入文件的路径 + 文件名 + 文件后缀
  • options:配置对象(可选参数)
    • flags:打开文件要执行的操作,默认值:w
    • encoding:设置文件的编码方式,默认值:utf8
    • fd : 文件统一标识符,linux下文件标识符
    • mode:设置文件的操作权限,默认值是:0o666 = 0o222 + 0o444
    • autoClose : 自动关闭文件,默认值:true
    • emitClose : 关闭文件,默认值:true
    • start : 整数值,写入文件的起始位置(偏移量)
  • 返回值:<fs.WriteStream>(一个可写流)

文件流写入的过程:

  1. 创建一个可写流(水管搭建好了)
    let ws = fs.createWriteStream(__dirname+ '/demo.txt', {start:10})
    
    1
  2. 检测流的状态(只要用到了流,就必须监测流的状态)
    ws.on('open',function () {
        console.log('可写流打开了')
    })
    ws.on('close',function () {
        console.log('可写流关闭了')
    })
    
    1
    2
    3
    4
    5
    6
  3. 使用可写流写入数据
    ws.write('美女\n')
    ws.write('霉女?\n')
    ws.write('到底是哪一个?\n')
    
    1
    2
    3
  4. 关闭可写流(水管不用了,得收起来)
    方式一:在 Node 的 v8 版本中,要用 end 方法关闭流,否则可能造成数据丢失。
    ws.end();
    
    1
    方式二:close 方法关闭流在 Node V8 可能造成数据丢失。
    ws.close() 
    
    1

# 3. 文件读取

文件读取也有两种方法:

// 同步
fs.readFileSync(path[, options])
// 异步
fs.readFile(path[, options], callback)
1
2
3
4

# 3.1 简单文件读取

语法:

fs.readFile(path[, options], callback(arr, data))
1

参数说明:

  • path:要读取文件的路径+文件名+后缀
  • options:配置对象(可选)
  • callback:回调函数
    • err:错误对象
    • data:读取出来的数据

[!TIP] 当文件读入成功,则 err 为 null,data 为读取到的数据。若当文件读入失败,则 err 为异常对象,data 为空。

let fs = require('fs')

fs.readFile(__dirname + '/test.mp4', function (err, data) {
    if (err) console.log(err)
    else console.log(data)
    fs.writeFile('../haha.mp4', data, function (err) {
        if (err) console.log(err)
        else console.log('文件写入成功')
    })

})
1
2
3
4
5
6
7
8
9
10
11

为什么读取出来的东西是Buffer? 用户存储的不一定是纯文本。

[!warning] 简单文件写入和简单文件读取,都是一次性把所有要读取或要写入的内容加到内存中,容易造成内存泄露。

# 3.2 流式文件读取

对于一个较大的文件,我们不能通过简单方式读取。因为简单方式是一次性读取,内存可能不够用。这个时候我们可以使用流式读取,分多次读取。

创建一个文件读取流语法:

fs.createReadStream(path[, options])
1

参数说明:

  • path:要读取的文件路径 + 文件名 + 后缀
  • options:可选配置项
    • flags
    • encoding
    • fd
    • mode
    • autoClose
    • emitClose
    • start:起始偏移量
    • end:结束偏移量
    • highWaterMark:每次读取数据的大小,默认值是 64 * 1024(64KB)

流式读取(并写入到一个新文件中)文件过程:

let { createReadStream, createWriteStream } = require('fs')

//创建一个可读流
let rs = createReadStream(__dirname + '/music.mp3', {
    // 10M
    highWaterMark: 10 * 1024 * 1024,
    //  start end 参数一般不用
    // start:60000,
    // end:120000
})

//创建一个可写流
let ws = createWriteStream('../haha.mp3')

// 只要用到了流,就必须监测流的状态
rs.on('open', function () {
    console.log('可读流打开了')
})
rs.on('close', function () {
    console.log('可读流关闭了')
    // 正确关闭流方式:当没有数据可读,读取流关闭,则写入流也关闭
    ws.close()
})
ws.on('open', function () {
    console.log('可写流打开了')
})
ws.on('close', function () {
    console.log('可写流关闭了')
})

// 给可读流绑定一个data事件,就会触发可读流自动读取内容。
rs.on('data', function (data) {
    // Buffer实例的length属性,是表示该Buffer实例占用内存空间的大小
    // 输出的是65536,每次读取64KB的内容
    console.log(data.length)
    ws.write(data)
    // ws.close() 
    //若在此处关闭流,会写入一次,后续数据丢失
})
// ws.close()
//若在此处关闭流,导致无法写入数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
编辑此页 (opens new window)
上次更新: 2024/12/28, 18:32:08
Buffer 缓冲器
MongoDB 非关系型数据库

← Buffer 缓冲器 MongoDB 非关系型数据库→

Theme by Vdoing | Copyright © 2019-2025 程序员scholar
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式