NodeJS 之 fs 模块(路径动态拼接问题)

news/2024/7/7 7:44:42 标签: javascript, NodeJS, 后端, 路径动态拼接问题, fs

NodeJSfs 模块(路径动态拼接问题

  • 参考
  • 描述
  • 问题
      • 描述
      • 准备工作
          • content.txt
          • main.js
      • 复现
          • 前奏
          • 惊雷
          • 再探
          • 分析
  • 解决
      • __dirname
      • path 模块
          • path.join()
      • 解决

参考

项目参考
NodeJSAPI 官方文档
哔哩哔哩黑马程序员

描述

项目描述
操作系统Windows 10 专业版
NodeJS18.13.0

问题

描述

在使用 NodeJSfs 模块处理文件时,你可能经常在路径中使用 ./…/ 来指明某个文件(夹)位于当前工作目录或其父目录中。使用相对路径指定文件的位置相比使用绝对路径来指定文件的位置要方便许多,但这样可能会导致意外事故的发生。

准备工作

content.txt

这是 content.txt 文件中的内容,我们稍后将通过 fs 模块读取该文件。

隐约雷鸣,阴霾天空。但盼风雨来,能留你在此。
隐约雷鸣,阴霾天空。即使无天雨,我亦留此地。

main.js

这是 main.js 文件中的内容,稍后我将通过 NodeJS 执行该文件以读取 content.txt 文件中的内容。

javascript">const fs = require('fs');

// 尝试读取当前工作目录下的 content.txt 文件
fs.readFile('./content.txt', 'utf-8', (err, data) => {
    if(err){
        console.log('【文件读取失败】')
    }else{
        console.log(data)
    }
})

注:

  1. content.txtmain.js 文件位于同一目录之下。
  2. content.txtmain.js 文件所在的路径分别为:
    • C:\Users\36683\Template\content.txt
    • C:\Users\36683\Template\main.js

复现

前奏

进入 main.js 所在的目录下后,在终端中输入如下命令以执行 main.js 文件中的内容。

node main.js

终端将输出如下内容:

隐约雷鸣,阴霾天空。但盼风雨来,能留你在此。
隐约雷鸣,阴霾天空。即使无天雨,我亦留此地。

惊雷

首先,让我们使用如下命令进入当前目录的父级目录中:

cd ..

执行如下命令以读取 content.txt 文件中的内容:

node Template/main.js

打印结果为:

【文件读取失败】

再探

由于我们使用 fs 模块捕获了错误,所以错误信息并没有打印出来。我们需要获得错误信息以对该问题产生的原因有更准确的了解。

main.js 文件中的内容修改为:

javascript">const fs = require('fs');

// 尝试读取当前工作目录下的 content.txt 文件
fs.readFile('./content.txt', 'utf-8', (err, data) => {
    if(err){
        console.log('【文件读取失败】');
        // 打印错误信息
        console.log(err.message);
    }else{
        console.log(data)
    }
})

再次执行如下命令以读取 content.txt 文件中的内容:

node Template/main.js

打印结果:

【文件读取失败】
ENOENT: no such file or directory, open ‘C:\Users\36683\content.txt’

分析

content.txt 文件的路径应该为:

C:\Users\36683\Template\content.txt

可再错误信息中得到的却是:

C:\Users\36683\content.txt

这是因为,NodeJS 在执行 JavaScript 文件时,会将其中的相对路径与执行命令时所在的工作目录进行拼接。

解决

前面你所认识到的问题便是路径拼接问题,该问题的解决方法有两种:

  1. 使用绝对路径而非相对路径指定计算机中的文件。
  2. 通过 NodeJS 来获取被 NodeJS 执行的文件所在的文件夹的路径与目标文件(将要读取的文件)的相对路径进行拼接得到目标文件的绝对路径。

第一种解决方式相信各位都懂;第二种方式更具灵活性,不用担心将项目文件(包含 content.txtmain.js 文件的文件夹)转移到其他计算机后无法正常使用。

__dirname

__dirnameNodeJS 中内置的一个变量,保存着该文件所在的目录的路径。

首先,让我们在终端中使用如下命令切换工作目录至 main.js 文件所在的文件夹中。

cd Template

进来该目录后,将 main.js 修改为如下内容。

javascript">const fs = require('fs');

// 尝试读取当前工作目录下的 content.txt 文件
fs.readFile('./content.txt', 'utf-8', (err, data) => {
    if(err){
        console.log('【文件读取失败】');
        console.log(err.message);
    }else{
        console.log(__dirname)
    }
})

执行结果为:

C:\Users\36683\Template

path 模块

在使用 __dirname 获取到被 NodeJS 执行的文件所在的文件夹的路径后,我们需要将其与目标文件(将要读取的文件)的相对路径进行拼接。

路径的拼接尽量不要使用像拼接字符串那样使用 + 号进行拼接,更好的方法是使用 NodeJS 内置的 path 模块中 path.join() 来进行拼接。

path.join()

Windows 使用的文件分割符为 \ ,当然你也可以使用 / ,但这并不规范;而在 LinuxMacOS 中,操作系统使用的文件分割符均为 / ,在这些操作系统中,\ 将被理解为转义字符的前缀。

为了 提高程序在不同平台中的兼容性 ,我们需要正确的使用文件分隔符,而 path.join() 很好的解决了这个问题。

path.join() 方法使用特定于平台的分隔符作为定界符将所有给定的 path 片段连接在一起,然后规范化生成的路径。

javascript">path.join([...paths])
项目描述
pathspaths 为一个路径中所有被符号分割的文件(夹)名或盘符,你需要将这些片段按照一定的顺序传递给 path.join() 函数。

举个栗子:

javascript">const path = require('path');

result = path.join('c', 'TwoMoons', 'RedHeart');
console.log(result)

打印结果:

C:\Users\36683\Template

注:

由打印结果可以发现,path.join() 将我们传递给其的 c 转换为 C

解决

main.js 修改为如下内容后,切换工作目录为当前工作目录的父级目录。

javascript">const fs = require('fs');
const path = require('path');

const target = path.join(__dirname, 'content.txt')

// 尝试读取当前工作目录下的 content.txt 文件
fs.readFile(target, 'utf-8', (err, data) => {
    if(err){
        console.log('【文件读取失败】');
        console.log(err.message);
    }else{
        console.log(data)
    }
})

执行结果:

隐约雷鸣,阴霾天空。但盼风雨来,能留你在此。
隐约雷鸣,阴霾天空。即使无天雨,我亦留此地。

至此,路径动态拼接问题已成功解决。


http://www.niftyadmin.cn/n/28896.html

相关文章

(17)go-micro微服务Prometheus监控

文章目录一 Prometheus监控介绍1.微服务监控系统promethues介绍2.微服务监控系统promethues工作流程二 Prometheus监控重要组件和重要概念1.微服务监控系统promethues重要组件2.微服务监控系统promethues重要概念三 微服务监控系统grafana看板四 Prometheus监控Grafana看板安装…

力扣98.验证二叉搜索树

文章目录力扣98.验证二叉搜索树题目描述算法思路代码实现力扣98.验证二叉搜索树 题目描述 给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。 有效 二叉搜索树定义如下: 节点的左子树只包含 小于 当前节点的数。 节点的右子树只包含 …

模拟实现一个简单的命令行解释器(shell)

目录 前言 环境变量与本地变量 和环境变量相关的命令 获取环境变量的三种方法 第一种 第二种 第三种 进程地址空间 页表 为什么存在进程地址空间 第一 第二 第三 进程控制 进程的产生 进程终止 进程等待 进程替换 模拟实现一个shell 前言 我们通过各种指令来实现…

行列式的定义

排列的逆序数 对于一个排列,如果是从到到尾都是从小到大,那么逆序数(number of permutation inversions)就为0.只要出现一次大的在前,小的在后,逆序数就加一次。逆序数的符号是希腊字母τ\tauτ,读音为“涛",比如以下排列&am…

【网络安全】WiFi密码爆破教程

WiFi密码爆破教程前言一、什么是暴力破解?二、准备破解工具1.VMware Pro 16 虚拟机安装2. VMware安装Kali Linux3. kali监听无限网卡三、WiFi密码暴力破解1. 虚拟机连接USB网卡2. 扫描附近WiFi3. 查看目标WiFi连接设备4. 抓包5. 破解前言 暴力破解攻击是指攻击者通…

【Java开发】Spring Cloud 05 :远程服务调用Openfeign 替代 WebClient

在前边章节中,我们借助 Nacos 的服务发现能力,使用 WebClient 实现了服务间调用。从功能层面上来讲,我们已经完美地实现了微服务架构下的远程服务调用,但是从易用性的角度来看,这种实现方式似乎对开发人员并不怎么友好…

Cadence PCB仿真使用Allegro PCB SI查看仿真波形的方法图文教程

🏡《Cadence 开发合集目录》   🏡《Cadence PCB 仿真宝典目录》 目录 1,概述2,拓扑提取阶段仿真方法3,图纸设计阶段仿真方法4,总结1,概述 本文简单介绍使用Alegro PCB SI执行仿真查看仿真波形的两种方法。 2,拓扑提取阶段仿真方法 如下图在拓扑提取阶段,添加完激励…

华为OD机试 - 日志限流

题目描述 某软件系统会在运行过程中持续产生日志,系统每天运行N单位时间,运行期间每单位时间产生的日志条数保行在数组records中。records[i]表示第i单位时间内产生日志条数。 由于系统磁盘空间限制,每天可记录保存的日志总数上限为total条。 如果一天产生的日志总条数大于…