nodejs---fs模块,文件读写操作详解,自定义一个文件写入方法

2024-06-07 14:28

本文主要是介绍nodejs---fs模块,文件读写操作详解,自定义一个文件写入方法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

fs模块导入

Node.js 同时支持 CommonJS 和 ES 模块系统(自 Node.js v12 以来)

// 两种模块导入方式
import * as fs from 'fs';// Es6:这种方式需要在package.json中配置"type": "module"
const fs = require('fs');// commonJs:如果你只有一个单文件js那么你还是要使用这种方式导入

是否使用ES6的导入方式,取决于你是否有一个配置文件,或者就使用require导入

fs的读写文件方法

fs提供的文件操作方法包含3中模式:回调式,阻塞式,promise式

这里使用stat()方法举例,

检查文件信息 stat()

const fs = require('fs');// commonJs
const txt = '../public/file.txt'// 回调式
fs.stat(txt, (err, stats) => {if(err){console.log(err.message);}console.log(stats.isFile());
})// 阻塞式
try {const stats = fs.statSync(txt);
} catch (err) {console.error(err);
}
console.log(stats.isFile());// promise式
async function example() {try {const stats = await fs.stat(txt);} catch (err) {console.log(err);}console.log(stats.isFile());
}
example();

使用后面两种方法时需要使用try,catch来捕获错误,

这里要注意 :如果不存在txt路径的文件,会产生错误,这种错误式 被捕获的err提示的,并非式致命错误(直接终止程序),它会提示你没有这个文件,而后面对这个文件的操作也会无法执行,

读取文件内容 readFile()

// 读取文件, 读取文件内容,并返回一个字符串
fs.readFile(txt, 'utf8', (err, data) => {if(err){console.log(err.message);}console.log(data);
}) 

参数:文件路径,读取格式(默认式二进制流格式),回调参数,err错误信息,data读取的数据

同样的,readFile也支持三种模式:回调式,阻塞式,promise式,这里仅展示回调式

写入文件writeFile()

// 写入文件, 写入文件内容,
fs.writeFile(txt, 'hello world', (err) => {if(err){console.log(err.message);}console.log('写入成功');
})

参数:文件路径,写入的内容,回调参数,err错误信息

同样的,writeFile也支持三种模式:回调式,阻塞式,promise式,这里仅展示回调式

追加内容appendFile()

fs.appendFile(txt, 'hello world', (err) => {if(err){console.log(err.message);}console.log('追加成功');
})

参数:文件路径,写入的内容,回调参数,err错误信息

同样的,appendFile也支持三种模式:回调式,阻塞式,promise式,这里仅展示回调式

注意 writeFile会覆盖原内容,从起始位置开始写入,appendFile不覆盖原内容,从末尾位置开始写入

文件夹操作

判断一个文件夹是否存在
使用 fs.existsSync(),这里exists不推荐使用了,事实上,对于文件夹的操作都建议使用阻塞式,因为文件都必须在文件夹下操作,文件夹没有被获取的话,文件操作就无法正常执行
新建一个文件夹
使用 fs.mkdir() 或 fs.mkdirSync()  创建新文件夹
读取目录的内容
使用 fs.readdir() 或 fs.readdirSync() 读取目录的内容。
重命名文件夹
使用 fs.rename() 或 fs.renameSync()  重命名文件夹。
删除文件夹
使用 fs.rmdir() 或 fs.rmdirSync() 删除文件夹。

新建一个文件夹

这里展示如何新建一个文件夹,其他方法类似,想了解更多可以参考:在 Node.js 中使用文件夹 (nodejs.cn)

const fs = require('fs');
const path = "./public/";try {// 如果没有public文件夹则创建if (!fs.existsSync(path)) {fs.mkdirSync(path);}
} catch (err) {console.error(err);
}

封装一个setFile方法

了解了基本的读写操作后我们可以封装一个方法,

该函数接收一个文件名和一个文件内容作为参数,并将文件内容写入指定的文件中(没有则创建),路径是当前目录下新建一个public文件夹,并将文件至于public下面。

/*** @param {文件名称} baseName * @param {写入的内容} content * @param {内容是否覆盖} b 默认为false,不覆盖*/setFile(baseName,content,b)
module.exports.setFile = function (baseName, content, b = false) {// 如果没有public文件夹则创建try {if (!fs.existsSync(path)) {fs.mkdirSync(path);console.log("文件夹 public 创建成功");}} catch (err) {console.log(err);}// 判断文件是否存在,在open之前判断,回调结果在open之后fs.stat(path + baseName, (err) => {if (err) {// 文件不存在,产生错误// console.log(err);console.log(`文件 ${baseName} 创建成功`);}})if (!b) {// 不覆盖内容// fs.readFile(path + baseName, "utf-8",(err, data) => {//   if (err) {//     console.error(err);//   }//   // 读取出原来的内容拼接//   content = data + content;//   fs.writeFile(path + baseName, content, (err) => {//     if (err) {//       console.error(err);//     }//     console.log("写入成功");//   })// })fs.appendFile(path + baseName, content, (err) => {if (err) {console.error(err);} else {console.log("写入成功");}})} else {fs.writeFile(path + baseName, content, (err) => {if (err) {console.error(err);} else {console.log("写入成功");}})}}

在同目录下新建一个useSetFile.js导入这个方法

// 导出的模块是整个文件,需要通过属性引入使用里面的方法
const setFile = require('./setFile');const file = 'file.txt';
const content = 'Hello, World!';setFile.setFile(file, content);

在控制台执行node useSetFile.js

 

可以看到目录下多了一个public文件夹和file.txt文件,并且写入了两个hello,world!

数据流缓冲区读写---open,close,read,write方法

出来file后缀的文件操作方法,fs模块还有基于数据流的读写方法,关于二进制数据流可以参考:

js二进制数据,文件---ArrayBuffer,二进制数组_js arraybuffer()-CSDN博客

// 打开文件,'w+/a+' 获得读,写权限,文件流起始位置在开头/末尾(a相比于a+没有读取权限), 如果文件不存在则创建,读取文件后会覆盖原有文件
fs.open(txt, 'a', (err, fd) => {if(err){console.log(err.message);}// 关闭文件, 关闭文件后才能进行其他操作fs.close(fd, (err) => {if(err){console.log(err.message);}console.log('文件关闭成功');})
})
/*** fd, 使用fs.open打开成功后返回的文件描述符* buffer, 一个Buffer对象,v8引擎分配的一段内存* offset, 整数,从缓存区中读取/写入时的初始位置,以字节为单位* length, 整数,从缓存区中读取/写入数据的字节数* position, 整数,写入/读取文件初始位置;* callback(err, written, buffer), 写入操作执行完成后回调函数,written实际写入字节数,buffer被读取的缓存区对象*/
fs.write(fd, buffer, offset, length, position, callback);
fs.read(fd, buffer, offset, length, position, callback);

整体的使用结构为

open->read/write->close

open开始拿到fd,fd为一个整数,表示打开文件返回的文件描述符,window中又称文件句柄

后续操作以fd为文件标志进行操作

const fs = require('fs');
const path = __dirname+"/public/buffer.txt";// __dirname 当前文件所在目录的绝对路径
const buffer = new Buffer.from("你好");  //每一个汉字utf8编码是3个字节,英文是1个字节fs.open(path, 'a+', (err, fd) => {fs.write(fd,buffer,0,6,0, (err) => {// 0,6,0的含义,0,6从buffer中读取6个字节,0是开始读取的位置,0是写入的位置,写入文件的起始位置  if(err){console.log(err);}else{console.log("写入成功");}})fs.read(fd,buffer,0,6,0, (err, bytes) => {// 0,6,0的含义,0,6从buffer中写入6个字节,0是开始写入的位置,0是读取的位置,读取文件的起始位置if(err){console.log(err);}else{if(bytes > 0){console.log(buffer.slice(0, bytes).toString());//打印buffer中的内容fs.read(fd,buffer,0,6,null, (err, bytes) => {// 再次读取fd中的内容时,不标记出读取位置,默认为上次读取结束的位置,'a+'表示每次将位置放置在文件末尾if(err){console.log(err);}else{if(bytes > 0){console.log(buffer.slice(0, bytes).toString());}}})}fs.close(fd, (err) => {//结束本次文件读写if(err){console.log(err);}else{console.log("关闭文件成功");}})}})});

这种方式的逻辑更加精细,可以控制数据流缓存区的位置进行读写,

值得注意的是,read和write两个方法中的3个整数参数,前两个是指定给buffer数据流缓冲区的 ,最后一个是文件的位置,当你进行read读取时,是对文件进行读取,在将读取的内容写入buffer

当你进行write写入时,是对buffer进行读取,在将读取的内容写入文件 ,两者正好相反但是参数格式一致

完整代码总结和目录结构展示

file.js

// 两种模块导入方式
// import * as fs from 'fs';// Es6:这种方式需要在package.json中配置"type": "module"
const fs = require('fs');// commonJs
const path = require('path');const txt = '../public/file.txt'
const txtMsg = [path.dirname(txt),// 父级文件夹path.basename(txt),// 文件名,包括后缀path.extname(txt) // 文件后缀(扩展名)
]let f = 0 ;txtMsg.forEach(item => {console.log(item);
})// 同一代码块的回调执行顺序是 fs.open -> fs.close ->fs.stat -> fs.writeFile -> fs.readFile 打开文件,关闭文件,查看文件,写入文件,读取文件
// 打开文件,'w+/a+' 获得读,写权限,文件流起始位置在开头/末尾(a相比于a+没有读取权限), 如果文件不存在则创建,读取文件后会覆盖原有文件
fs.open(txt, 'a', (err, fd) => {if(err){console.log(err.message);}f = fd;console.log(fd); 
})// 读取文件, 读取文件内容,并返回一个字符串
fs.readFile(txt, 'utf8', (err, data) => {if(err){console.log(err.message);}console.log(data);
}) // 写入文件, 写入文件内容,
fs.writeFile(txt, 'hello world', (err) => {if(err){console.log(err.message);}console.log('写入成功');
})// 追加文件内容
fs.appendFile(txt, 'hello world', (err) => {if(err){console.log(err.message);}console.log('追加成功');
})// 关闭文件, 关闭文件后才能进行其他操作
fs.close(f, (err) => {if(err){console.log(err.message);}console.log('文件关闭成功');
})// 文件信息
fs.stat(txt, (err, stats) => {if(err){console.log(err.message);}console.log(stats.isFile());
})// 每次执行此文件,会先打开txt.txt文件,(此时内容已清空)关闭文件,写入内容,再读取文件内容

setFile.js

// 封装一个setFile函数,该函数接收一个文件名和一个文件内容作为参数,并将文件内容写入指定的文件中(没有则创建),路径是当前目录下新建一个public文件夹,并将文件至于public下面。
// setFile(baseName,content,b)const fs = require('fs');
const path = "./public/";/*** @param {文件名称} baseName * @param {写入的内容} content * @param {内容是否覆盖} b 默认为false,不覆盖*/module.exports.setFile = function (baseName, content, b = false) {// 如果没有public文件夹则创建try {if (!fs.existsSync(path)) {fs.mkdirSync(path);console.log("文件夹 public 创建成功");}} catch (err) {console.log(err);}// 判断文件是否存在,在open之前判断,回调结果在open之后fs.stat(path + baseName, (err) => {if (err) {// 文件不存在,产生错误// console.log(err);console.log(`文件 ${baseName} 创建成功`);}})if (!b) {// 不覆盖内容// fs.readFile(path + baseName, "utf-8",(err, data) => {//   if (err) {//     console.error(err);//   }//   // 读取出原来的内容拼接//   content = data + content;//   fs.writeFile(path + baseName, content, (err) => {//     if (err) {//       console.error(err);//     }//     console.log("写入成功");//   })// })fs.appendFile(path + baseName, content, (err) => {if (err) {console.error(err);} else {console.log("写入成功");}})} else {fs.writeFile(path + baseName, content, (err) => {if (err) {console.error(err);} else {console.log("写入成功");}})}
}

useSetFile.js

// 导出的模块是整个文件,需要通过属性引入使用里面的方法
const setFile = require('./setFile');const file = 'file.txt';
const content = 'Hello, World!';setFile.setFile(file, content);

buffer.js

const fs = require('fs');
const path = __dirname+"/public/buffer.txt";// __dirname 当前文件所在目录的绝对路径
const buffer = new Buffer.from("你好");  //每一个汉字utf8编码是3个字节,英文是1个字节fs.open(path, 'a+', (err, fd) => {fs.write(fd,buffer,0,6,0, (err) => {// 0,6,0的含义,0,6从buffer中读取6个字节,0是开始读取的位置,0是写入的位置,写入文件的起始位置  if(err){console.log(err);}else{console.log("写入成功");}})fs.read(fd,buffer,0,6,0, (err, bytes) => {// 0,6,0的含义,0,6从buffer中写入6个字节,0是开始写入的位置,0是读取的位置,读取文件的起始位置if(err){console.log(err);}else{if(bytes > 0){console.log(buffer.slice(0, bytes).toString());//打印buffer中的内容fs.read(fd,buffer,0,6,null, (err, bytes) => {// 再次读取fd中的内容时,不标记出读取位置,默认为上次读取结束的位置,'a+'表示每次将位置放置在文件末尾if(err){console.log(err);}else{if(bytes > 0){console.log(buffer.slice(0, bytes).toString());}}})}fs.close(fd, (err) => {//结束本次文件读写if(err){console.log(err);}else{console.log("关闭文件成功");}})}})});

目录结构

这篇关于nodejs---fs模块,文件读写操作详解,自定义一个文件写入方法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/1039429

相关文章

Olingo分析和实践之EDM 辅助序列化器详解(最佳实践)

《Olingo分析和实践之EDM辅助序列化器详解(最佳实践)》EDM辅助序列化器是ApacheOlingoOData框架中无需完整EDM模型的智能序列化工具,通过运行时类型推断实现灵活数据转换,适用... 目录概念与定义什么是 EDM 辅助序列化器?核心概念设计目标核心特点1. EDM 信息可选2. 智能类

Olingo分析和实践之ODataImpl详细分析(重要方法详解)

《Olingo分析和实践之ODataImpl详细分析(重要方法详解)》ODataImpl.java是ApacheOlingoOData框架的核心工厂类,负责创建序列化器、反序列化器和处理器等组件,... 目录概述主要职责类结构与继承关系核心功能分析1. 序列化器管理2. 反序列化器管理3. 处理器管理重要方

Python错误AttributeError: 'NoneType' object has no attribute问题的彻底解决方法

《Python错误AttributeError:NoneTypeobjecthasnoattribute问题的彻底解决方法》在Python项目开发和调试过程中,经常会碰到这样一个异常信息... 目录问题背景与概述错误解读:AttributeError: 'NoneType' object has no at

从入门到精通详解LangChain加载HTML内容的全攻略

《从入门到精通详解LangChain加载HTML内容的全攻略》这篇文章主要为大家详细介绍了如何用LangChain优雅地处理HTML内容,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录引言:当大语言模型遇见html一、HTML加载器为什么需要专门的HTML加载器核心加载器对比表二

Python使用openpyxl读取Excel的操作详解

《Python使用openpyxl读取Excel的操作详解》本文介绍了使用Python的openpyxl库进行Excel文件的创建、读写、数据操作、工作簿与工作表管理,包括创建工作簿、加载工作簿、操作... 目录1 概述1.1 图示1.2 安装第三方库2 工作簿 workbook2.1 创建:Workboo

Python实现中文文本处理与分析程序的示例详解

《Python实现中文文本处理与分析程序的示例详解》在当今信息爆炸的时代,文本数据的处理与分析成为了数据科学领域的重要课题,本文将使用Python开发一款基于Python的中文文本处理与分析程序,希望... 目录一、程序概述二、主要功能解析2.1 文件操作2.2 基础分析2.3 高级分析2.4 可视化2.5

Java实现预览与打印功能详解

《Java实现预览与打印功能详解》在Java中,打印功能主要依赖java.awt.print包,该包提供了与打印相关的一些关键类,比如PrinterJob和PageFormat,它们构成... 目录Java 打印系统概述打印预览与设置使用 PageFormat 和 PrinterJob 类设置页面格式与纸张

MySQL 8 中的一个强大功能 JSON_TABLE示例详解

《MySQL8中的一个强大功能JSON_TABLE示例详解》JSON_TABLE是MySQL8中引入的一个强大功能,它允许用户将JSON数据转换为关系表格式,从而可以更方便地在SQL查询中处理J... 目录基本语法示例示例查询解释应用场景不适用场景1. ‌jsON 数据结构过于复杂或动态变化‌2. ‌性能要

postgresql使用UUID函数的方法

《postgresql使用UUID函数的方法》本文给大家介绍postgresql使用UUID函数的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录PostgreSQL有两种生成uuid的方法。可以先通过sql查看是否已安装扩展函数,和可以安装的扩展函数

Python实现终端清屏的几种方式详解

《Python实现终端清屏的几种方式详解》在使用Python进行终端交互式编程时,我们经常需要清空当前终端屏幕的内容,本文为大家整理了几种常见的实现方法,有需要的小伙伴可以参考下... 目录方法一:使用 `os` 模块调用系统命令方法二:使用 `subprocess` 模块执行命令方法三:打印多个换行符模拟