NodeJS 之 fs 模块(路径动态拼接问题)
创始人
2024-05-15 04:19:03
0

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

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

参考

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

描述

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

问题

描述

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

准备工作

content.txt

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

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

main.js

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

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 文件中的内容修改为:

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

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

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

cd Template

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

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 片段连接在一起,然后规范化生成的路径。

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

举个栗子:

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

打印结果:

C:\Users\36683\Template

注:

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

解决

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

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)}
})

执行结果:

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

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

相关内容

热门资讯

捷豹安卓系统车载,捷豹安卓系统... 哇,你有没有想过,当你的手机和汽车融为一体,会是怎样的体验呢?想象你正驾驶着你的捷豹,车窗外的风景如...
安卓1到10系统,安卓1.0至... 你有没有想过,手机里的安卓系统就像是我们生活中的好朋友,从青涩的少年成长为稳重的青年呢?从安卓1.0...
安卓8.0停用系统应用,提升使... 你知道吗?最近安卓系统又来了一次大动作,那就是安卓8.0系统开始停用一些系统应用了。这可真是让人有点...
安卓系统修改mtu值,轻松提升... 你有没有想过,你的安卓手机其实是个小小的电脑呢?它里面藏着许多可以自定义的秘密功能,就像修改MTU值...
安卓平板改window系统,探... 你有没有想过,你的安卓平板其实可以摇身一变,变成一个Windows系统的电脑呢?没错,就是那种可以运...
时空猎人安卓苹果系统,探索无尽... 你知道吗?最近在手机游戏圈里,有一款叫做《时空猎人》的游戏可是火得一塌糊涂呢!不管是安卓用户还是苹果...
安卓9.0系统的电视,新一代电... 亲爱的读者们,你是否也像我一样,对科技新玩意儿充满好奇?今天,我要和你聊聊一个让人眼前一亮的话题——...
小pc安装安卓系统,轻松安装安... 你有没有想过,你的小PC也能变身成为安卓系统的超级玩家呢?没错,就是那个平时默默无闻的小家伙,现在也...
高通备份安卓系统,全方位数据安... 你知道吗?在这个科技飞速发展的时代,手机备份可是个不得不提的话题。尤其是对于安卓用户来说,选择一个靠...
谷歌安卓系统有多少,从诞生到全... 你有没有想过,那个无处不在的谷歌安卓系统,究竟在全球有多少用户呢?它就像一个神秘的数字,每天都在悄悄...
fc黄金传说安卓系统,畅享复古... 你有没有听说最近安卓系统上的一款超酷的游戏——《FC黄金传说》?这款游戏可是让不少玩家都沉迷其中,今...
变小的我安卓系统,安卓系统演变... 你有没有发现,最近你的手机好像变轻了?没错,说的就是你,那个陪伴你多年的安卓系统。它悄无声息地进行了...
vivo安卓系统小彩蛋,体验科... 你知道吗?在vivo的安卓系统中,竟然隐藏着一些超有趣的小彩蛋!这些小彩蛋就像是在手机里埋下的宝藏,...
安卓系统如何强制重启,安卓系统... 手机突然卡壳了,是不是又该给它来个“大保健”了?没错,今天就来聊聊安卓系统如何强制重启。别小看这个看...
全民飞行团安卓系统,体验指尖上... 你知道吗?最近在手机游戏圈里,有个叫做“全民飞行团”的新星正在闪耀!这款游戏不仅吸引了无数玩家的目光...
安卓鸿蒙系统壁纸软件,壁纸软件... 亲爱的手机控们,你是否厌倦了单调的壁纸?想要给你的安卓手机换上充满科技感的鸿蒙系统风格壁纸?那就跟我...
安卓系统ram重新分区,提升系... 你有没有发现,你的安卓手机最近有点儿卡呢?别急,别急,今天就来给你揭秘如何给安卓系统的RAM来个重新...
迷你退出安卓系统了吗,转型新篇... 最近有没有发现你的手机上那个可爱的迷你退出图标突然不见了?别急,让我来给你揭秘迷你退出安卓系统了吗的...
华为优先使用安卓系统,打造自主... 你知道吗?最近科技圈里有个大动作,那就是华为宣布优先使用安卓系统。这可不是一个简单的决定,它背后可是...
安卓系统隐藏了设置,隐藏设置功... 你知道吗?安卓系统这个大宝藏里,竟然隐藏着一些不为人知的设置!是不是听起来就有点小激动呢?别急,今天...