Nodejs 文件 与 路径 相关用法实例解析

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: Nodejs 文件 与 路径 相关用法实例解析

Nodejs 文件 与 路径 相关用法


1.路径

(1)引入path模块

const path = require('path');

(2)当前文件所在目录的绝对路径:__dirname

console.log("__dirname =",__dirname);
__dirname = g:\NodeJs\fs

(3)路径连接:path.join()

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

  • 零长度的 path 片段被忽略;
  • 如果连接的路径字符串是零长度字符串,则将返回 ‘.’,表示当前工作目录。
const joined_path = path.join(__dirname, 'NodeJs', 'textFile.txt')
console.log(joined_path);
g:\NodeJs\fs\NodeJs\textFile.txt

(4)获取文件名:path.basename()

const filename = path.basename('g:\\NodeJs\\fs\\NodeJs\\textFile.txt')
console.log(filename);
textFile.txt

(5)获取文件扩展名:path.extname()

const surfix = path.extname('g:\\NodeJs\\fs\\NodeJs\\textFile.txt')
console.log(surfix);
.txt

(6)分解绝对路径:path.parse()

  • root: 根目录/ 磁盘名
  • dir: 文件或文件夹所在文件夹完整绝对路径
  • base: 文件/文件夹名加扩展(非绝对路径)
  • ext: 扩展名
  • name: 文件/文件夹名
const parserst = path.parse('g:\\NodeJs\\fs\\NodeJs\\textFile.txt')
console.log(parserst);console.log();
{
  root: 'g:\\',
  dir: 'g:\\NodeJs\\fs\\NodeJs',
  base: 'textFile.txt',
  ext: '.txt',
  name: 'textFile'
}

(7)从对象返回路径字符串:path.format()

path.parse()功能相反

const pt = path.format({
  root: 'g:\\',
  dir: 'g:\\NodeJs\\fs\\NodeJs',
  base: 'textFile.txt'
});
console.log(pt);
g:\NodeJs\fs\NodeJs\textFile.txt

(8)判断是否是绝对路径:path.isAbsolute()

const isAbs1 = path.isAbsolute('g:\\NodeJs\\fs\\NodeJs\\textFile.txt');
const isAbs2 = path.isAbsolute('textFile.txt');
console.log('isAbs1是绝对路径吗:',isAbs1);
console.log('isAbs2是绝对路径吗:',isAbs2);
isAbs1是绝对路径吗: true
isAbs2是绝对路径吗: false

(9)返回两端路径之间的相对路径表示:path.relative()

const path1 = '/data/orandea/test/aaa';
const path2 = '/data/orandea/impl/bbb';
const relativepath = path.relative(path1,path2)
console.log('path2在path1的相对表示为:',relativepath);console.log();
path2在path1的相对表示为: ..\..\impl\bbb

(10)将路径或路径片段的序列解析为绝对路径:path.resolve()

// 给定的路径序列从右到左处理,每个后续的 path 会被追加到前面,直到构建绝对路径。
console.log(path.resolve('/foo/bar', '/tmp/file/'));
console.log(path.resolve('NodeJs', 'fs/NodeJs/', 'textFile'));
G:\tmp\file
G:\NodeJs\NodeJs\fs\NodeJs\textFile

(11)将路径分割为数组:path.sep

(注意与不同系统的路径分隔符有关)

console.log('foo\\bar\\baz'.split(path.sep));console.log();
[ 'foo', 'bar', 'baz' ]

注意区分不同系统上的路径分隔符不同。

(12)获取当前操作系统上的路径定界符:path.delimiter

console.log('路径定界符为:',path.delimiter);
路径定界符为: ;

应用

const processEnvPATH = process.env.PATH
console.log(processEnvPATH);
console.log(processEnvPATH.split(path.delimiter));console.log();
C:\Program Files\PowerShell\7;C:\Program Files\AdoptOpenJDK\jdk-11.0.8.10-hotspot\bin;C:\Program Files (x86)\Common Files\Oracle\Java\javapath;C:\Program Files\Common Files\Oracle\Java\javapath;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32\OpenSSH\;C:\Program Files\PowerShell\7\;D:\Program Files\Dart\dart-sdk\bin;C:\Program Files\PuTTY\;D:\Program Files\nodejs\;C:\ProgramData\chocolatey\bin;C:\Program Files (x86)\Yarn\bin\;C:\Program Files\Docker\Docker\resources\bin;C:\ProgramData\DockerDesktop\version-bin;C:\Program Files\dotnet\;C:\Program Files\Git\cmd;C:\Program Files\MySQL\MySQL Shell 8.0\bin\;C:\Users\a2911\AppData\Local\Programs\Python\Python39\Scripts\;C:\Users\a2911\AppData\Local\Programs\Python\Python39\;C:\Users\a2911\AppData\Local\Microsoft\WindowsApps;D:\flutter;C:\Users\a2911\AppData\Local\GitHubDesktop\bin;C:\Users\a2911\AppData\Local\Programs\Microsoft VS Code\bin;C:\Users\a2911\AppData\Local\Yarn\bin;D:\flutter\bin;C:\Users\a2911\.dotnet\tools;D:\Program Files\Nox\bin;C:\Users\a2911\AppData\Roaming\npm;
[
  'C:\\Program Files\\PowerShell\\7',
  'C:\\Program Files\\AdoptOpenJDK\\jdk-11.0.8.10-hotspot\\bin',
  'C:\\Program Files (x86)\\Common Files\\Oracle\\Java\\javapath',
  'C:\\Program Files\\Common Files\\Oracle\\Java\\javapath',
  'C:\\WINDOWS\\system32',
  'C:\\WINDOWS',
  'C:\\WINDOWS\\System32\\Wbem',
  'C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\',
  'C:\\WINDOWS\\System32\\OpenSSH\\',
  'C:\\Program Files\\PowerShell\\7\\',
  'D:\\Program Files\\Dart\\dart-sdk\\bin',
  'C:\\Program Files\\PuTTY\\',
  'D:\\Program Files\\nodejs\\',
  'C:\\ProgramData\\chocolatey\\bin',
  'C:\\Program Files (x86)\\Yarn\\bin\\',
  'C:\\Program Files\\Docker\\Docker\\resources\\bin',
  'C:\\ProgramData\\DockerDesktop\\version-bin',
  'C:\\Program Files\\dotnet\\',
  'C:\\Program Files\\Git\\cmd',
  'C:\\Program Files\\MySQL\\MySQL Shell 8.0\\bin\\',
  'C:\\Users\\a2911\\AppData\\Local\\Programs\\Python\\Python39\\Scripts\\',
  'C:\\Users\\a2911\\AppData\\Local\\Programs\\Python\\Python39\\',
  'C:\\Users\\a2911\\AppData\\Local\\Microsoft\\WindowsApps',
  'D:\\flutter',
  'C:\\Users\\a2911\\AppData\\Local\\GitHubDesktop\\bin',
  'C:\\Users\\a2911\\AppData\\Local\\Programs\\Microsoft VS Code\\bin',
  'C:\\Users\\a2911\\AppData\\Local\\Yarn\\bin',
  'D:\\flutter\\bin',
  'C:\\Users\\a2911\\.dotnet\\tools',
  'D:\\Program Files\\Nox\\bin',
  'C:\\Users\\a2911\\AppData\\Roaming\\npm',
  ''
]

(13)返回所在文件夹绝对路径:path.dirname()

const dir = path.dirname('g:\\NodeJs\\fs\\NodeJs\\textFile.txt');
console.log(dir);
g:\NodeJs\fs\NodeJs

2. 文件

(1)引入相关模块

const path = require('path');

(2)异步地获取指定文件的相关信息:access()

const file = 'g:\\NodeJs\\textFile.txt';
// 检查当前目录中是否存在该文件。
fs.access(file, fs.constants.F_OK, (err) => {
  console.log(`${file} ${err ? '不存在' : '存在'}`);
});
// 检查文件是否可读。
fs.access(file, fs.constants.R_OK, (err) => {
  console.log(`${file} ${err ? '不可读' : '可读'}`);
});
// 检查文件是否可写。
fs.access(file, fs.constants.W_OK, (err) => {
  console.log(`${file} ${err ? '不可写' : '可写'}`);
});
// 检查当前目录中是否存在文件,是否可写。
fs.access(file, fs.constants.F_OK | fs.constants.W_OK, (err) => {
  if (err) {
    console.error(
      `${file} ${err.code === 'ENOENT' ? '不存在' : '是 只读文件'}`);
  } else {
    console.log(`${file} 存在, 并且它是可写的`);
  }
});
g:\NodeJs\textFile.txt 存在
g:\NodeJs\textFile.txt 可读
g:\NodeJs\textFile.txt 可写
g:\NodeJs\textFile.txt 存在, 并且它是可写的

(3)复制文件(自动创建或覆盖目标):copyFile()

let sourceFile = 'g:\\NodeJs\\textfile.txt';
let destinationFile = 'g:\\NodeJs\\textfile.txt';
// 定义复制操作后执行的回调函数
function callBack(err) {
  if (err) {throw err}
  else{
    console.log('文件顺利复制完成');
  };
}
fs.copyFile(sourceFile, destinationFile, callBack);
文件顺利复制完成

(4)复制文件(文件存在则报错):fs.constants.COPYFILE_EXCL

let sourceFile = 'g:\\NodeJs\\textfile.txt';
let destinationFile = 'g:\\NodeJs\\textfile.txt';
function callBack(err) {
  if (err) throw err;
  console.log('文件顺利复制完成');
}
fs.copyFile(sourceFile, destinationFile, fs.constants.COPYFILE_EXCL, callBack);
[Error: EEXIST: file already exists, copyfile 'g:\NodeJs\textfile.txt' -> 'g:\NodeJs\textfile.txt'] {
  errno: -4075,
  code: 'EEXIST',
  syscall: 'copyfile',
  path: 'g:\\NodeJs\\textfile.txt',
  dest: 'g:\\NodeJs\\textfile.txt'
}

(5)打开文件:open()

let target = 'G:\\NodeJs\\fs\\a.txt'
let a =  fs.open(target, 'r', (err,fd)=>{
  if(err){throw err}
  else{
    console.log("文件已在内存中加载");
  }
})

注:

fs.open(path[, flags[, mode]], callback)

  • path:文件路径
  • flags:文件打开方式;
  • mode(可选):文件权限模式,默认为可读写;
  • Callback:回调函数,带有err和fd两个参数。

其中回调函数callback(err,fd)的两个参数中:

  • err:打开时的异常;
  • fd文件描述符
    一个文件打开以后,需要在操作完后对其关闭(见关闭文件:close()部分)以释放内存资源,并确认其正确关闭,这是需要用到这些曾今打开过的文件的文件描述符。也就是说该参数是用来跟踪一个已经打开的文件的,他在读取方法read()和关闭方法close()中都需要用到。
flag 含义
r 以只读模式打开文件,文件不存在时抛出异常
r+ 以读写模式打开文件,文件不存在时抛出异常
rs 以同步方式读取文件
rs+ 以同步方式读写文件
w 以只写模式打开文件,文件不存在时自动将其创建
wx 以只写模式打开文件,如果文件路径存在则写入失败
w+ 以读写模式打开文件,文件不存在时自动将其创建
wx+ 以读写模式打开文件,如果文件路径存在则写入失败
a 以追加模式打开文件,文件不存在时自动创建
ax 以追加模式打开文件,文件存在时将导致追加失败

(6)关闭文件:close()

该方法时open()的逆过程,需要接收open()方法返回的fd(文件描述符)参数以跟踪一个打开的文件进行关闭。

let target = 'G:\\NodeJs\\fs\\a.txt'
let a =  fs.open(target, 'r', (err,fd)=>{
  if(err){throw err}
  else{
    console.log("文件已在内存中加载");
    fs.close(fd, (error)=>{
      if(error){console.log(error)}
      else{
        console.log("文件关闭成功");
      }
    })
  }
})
文件已在内存中加载
文件关闭成功

(7)写入文件:writeFile()

let file = 'message.txt';
const data = new Uint8Array(Buffer.from('这是一些用于写入的文字'));
fs.writeFile(file, data, (err) => {
  if (err) throw err;
  console.log('文件已被写入');
});
文件已被写入

可以看到生成了一个文本文件:

(8)异步地将数据追加到文件:appendFile()

如果该文件尚不存在,则将自动创建该文件

// 将数据追加到文件,如果该文件尚不存在,则创建该文件
let file_path = 'g:\\NodeJs\\newfile.txt';
let datas = 'some text to append...'
fs.appendFile(file_path, datas, (err) => {
  if (err) throw err;
  console.log('The ' + datas + ', was appended to file!');
});

(9)读取文件:readFile()

假设我们在path指定处有一个文本,其内容为文本:这里有一些文字

直接读取这个文本文件:

let path = './fs/a.txt';
fs.readFile(path , (err, data) => {
  if (err) {throw err}
  else{console.log(data)}
});
<Buffer e8 bf 99 e9 87 8c e6 9c 89 e4 b8 80 e4 ba 9b e6 96 87 e5 ad 97>

可以看到由于未指定编码,则返回原始缓冲区数据。由于此处文本是先前使用utf-8格式保存的,我们可以这样读取:

fs.readFile('./fs/a.txt', 'utf8', (err, data) => {
  if (err) {throw err}
  else{console.log(data)}
});
这里有一些文字

注:这里这API都是异步的,且有相应的同步API,函数名相差不过多了一个Sync,比如我们也可以使用同步API读取文件:

let uts8Text = fs.readFileSync('./fs/a.txt',"utf8",'r+');
console.log(uts8Text)
这里有一些文字

(10)读取文件:read()

该方法需要提供以open()方法打开所返回的fd(文件资源定位符)参数作为参数。其格式为:

fs.read(fd, [options,] callback)

  • fd:通过open()方法返回的文件描述符;
  • buffer(可选):数据写入的缓冲区;
  • offset(可选):写入缓冲区时的写入偏移量;
  • length(可选):要从文件中读取的字节数;
  • position(可选):文件读取的起始位置,当为null时,就会从当前文件指针的位置进行读取。
let target = 'G:\\NodeJs\\fs\\a.txt'
fs.open(target, 'r', (err,fd)=>{
  if(err){throw err}
  else{
    console.log("文件已加载\n");
    let readUf = Buffer.alloc(1024); 
    let offset = 0;
    let length = readUf.length;
    let position = null;
    fs.read(fd, readUf, offset, length, position, (ery, bytesRead)=>{
      if(ery){throw err}
      else{
        console.log('读取文件大小',bytesRead +'bytes\n');
        let rst = readUf.slice(0,bytesRead);
        console.log('Buffer形式:',rst,'\n');
        console.log('以UTF-8编码转为字符串:',rst.toString('utf8'),'\n');
        fs.close(fd, (error)=>{
          if(error){console.log(error)}
          else{
            console.log("文件关闭成功");
          }
        })
      }
    })
  }
})
文件已加载
读取文件大小 36bytes
Buffer形式: <Buffer e8 bf 99 e9 87 8c e6 9c 89 e4 b8 80 e4 ba 9b e7 94 a8 e4 ba 8e e8 af bb e5 8f 96 e7 9a 84 e6 96 87 e5 ad 97> 
以UTF-8编码转为字符串: 这里有一些用于读取的文字
文件关闭成功

(11)异步地创建文件夹:mkdir()

fs.mkdir('./newFolder', { recursive: true }, (err) => {
  if (err) {throw err}
  else{
    console.log('新文件夹创建成功');
  };
});
新文件夹创建成功

如果成功,则将在指定目录下看到一个新的名为newFolder的文件夹。

(12)异步地删除文件和目录:rm()

function callBack(err) {
  if (err) throw err;
  console.log('文件删除完成');
}
fs.rm('a.text', {force: false , maxRetries: 0, recursive: false, retryDelay: 100,}, callBack)

如果文件不存在:

[Error: ENOENT: no such file or directory, stat 'xxxxxx'] {
  errno: -4058,
  code: 'ENOENT',
  syscall: 'stat',
  path: 'xxxxxx'
}

(13)异步地删除目录:fs.rmdir

在文件(而不是目录)上使用 fs.rmdir(),则在 Windows 上会导致 ENOENT 错误,在 POSIX 上会导致 ENOTDIR 错误。

function callBack(err) {
  if (err) throw err;
  console.log('文件夹删除完成');
}
fs.rm('folder', { maxRetries: 0, recursive: false, retryDelay: 100,}, callBack)

(14)读取文件夹(中的所有项目的名字):fs.readdir()

读取目录,其读取的内容既包括文件名也包括目录名。(不是绝对路径表示)

let dirName = 'G:\\mobile-flutter\\jcstdio\\assets\\coder\\statics\\css';
fs.readdir(dirName,{encoding: 'utf8', withFileTypes: false },(err:any, data:string[]) =>{
  if (err) {throw err
  }else{console.log(data);
  }
});
[
  'app.6605356c.css',
  'chunk-vendors.574a9ade.css',
  'login.6d2c5898.css'
]

获取给定文件夹中所有内容(文件和文件夹)的绝对路径

没有直接的方法,不过也很简单:

let dirName = 'G:\\mobile-flutter\\jcstdio\\assets\\coder\\statics\\css';
fs.readdir(dirName,{encoding: 'utf8', withFileTypes: false },(err:any, data:string[]) =>{
  if (err) {throw err}
  else{
    for(let i =0; i<data.length;i++){
      data[i] = path.join(dirName,data[i]);
    };
    console.log(data);
  }
});

如果withFileTypes参数为true,则返回项目中将带有文件类型信息,如:

[
  Dirent { name: 'app.6605356c.css', [Symbol(type)]: 1 },
  Dirent { name: 'chunk-vendors.574a9ade.css', [Symbol(type)]: 1 },
  Dirent { name: 'login.6d2c5898.css', [Symbol(type)]: 1 }
]

注:其相应的同步函数为readFileSync(),用法相同,如:

let dirName = 'G:\\mobile-flutter\\jcstdio\\assets\\coder\\statics\\css';
let ary = fs.readdirSync(dirName, 'utf8');
console.log(ary);
[
  'app.6605356c.css',
  'chunk-vendors.574a9ade.css',
  'login.6d2c5898.css'
]

另外,有对应的同步API为readdirSync(),其用法基本用法基本相似:

let dirName = 'G:\\mobile-flutter\\jcstdio\\assets\\coder\\statics\\css';
let a = fs.readdirSync(dirName, 'utf8', false)
console.log(a);
[
  'app.6605356c.css',
  'chunk-vendors.574a9ade.css',
  'login.6d2c5898.css'
]

如果要返回文件夹中所有文件的完整路径,可以和之前用同样的方法:

function getDirItemsAbsPath(dirName:string):string[]{
  let absPaths:string[] = [];
  fs.readdirSync(dirName, 'utf8', false).forEach((elem:string) => {
    absPaths.push(path.join(dirName,elem))
  });
  return absPaths
}
let dirName = 'G:\\mobile-flutter\\jcstdio\\assets\\coder\\statics\\css';
let dirItemsAbsPath = getDirItemsAbsPath(dirName)
console.log(dirItemsAbsPath);
[
  'G:\\mobile-flutter\\jcstdio\\assets\\coder\\statics\\css\\app.6605356c.css',
  'G:\\mobile-flutter\\jcstdio\\assets\\coder\\statics\\css\\chunk-vendors.574a9ade.css',
  'G:\\mobile-flutter\\jcstdio\\assets\\coder\\statics\\css\\login.6d2c5898.css'
]

(15)创建名为 path 指向 target 的链接:symlink()

function callBack(err) {
  if (err) throw err;
}
let target = 'G:\\NodeJs\\fs\\a.txt'
let path = 'C:\\Users\\a2911\\Desktop\\a_link'
fs.symlink(target, path, callBack);

成功执行后,可以看到path指定处产生了一个链接名为a_link(Windows中也称快捷方式)

该函数也有其对应的同步函数,为:symlinkSync()

用法基本类似。

目录
相关文章
|
1月前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
71 2
|
2天前
|
数据挖掘 vr&ar C++
让UE自动运行Python脚本:实现与实例解析
本文介绍如何配置Unreal Engine(UE)以自动运行Python脚本,提高开发效率。通过安装Python、配置UE环境及使用第三方插件,实现Python与UE的集成。结合蓝图和C++示例,展示自动化任务处理、关卡生成及数据分析等应用场景。
17 5
|
1月前
|
存储 负载均衡 监控
数据库多实例的深入解析
【10月更文挑战第24天】数据库多实例是一种重要的数据库架构方式,它为数据库的高效运行和灵活管理提供了多种优势。在实际应用中,需要根据具体的业务需求和技术环境,合理选择和配置多实例,以充分发挥其优势,提高数据库系统的性能和可靠性。随着技术的不断发展和进步,数据库多实例技术也将不断完善和创新,为数据库管理带来更多的可能性和便利。
109 57
|
19天前
|
存储 网络协议 算法
【C语言】进制转换无难事:二进制、十进制、八进制与十六进制的全解析与实例
进制转换是计算机编程中常见的操作。在C语言中,了解如何在不同进制之间转换数据对于处理和显示数据非常重要。本文将详细介绍如何在二进制、十进制、八进制和十六进制之间进行转换。
29 5
|
27天前
|
存储 机器学习/深度学习 编解码
阿里云服务器计算型c8i实例解析:实例规格性能及使用场景和最新价格参考
计算型c8i实例作为阿里云服务器家族中的重要成员,以其卓越的计算性能、稳定的算力输出、强劲的I/O引擎以及芯片级的安全加固,广泛适用于机器学习推理、数据分析、批量计算、视频编码、游戏服务器前端、高性能科学和工程应用以及Web前端服务器等多种场景。本文将全面介绍阿里云服务器计算型c8i实例,从规格族特性、适用场景、详细规格指标、性能优势、实际应用案例,到最新的活动价格,以供大家参考。
|
29天前
|
消息中间件 存储 Java
RocketMQ文件刷盘机制深度解析与Java模拟实现
【11月更文挑战第22天】在现代分布式系统中,消息队列(Message Queue, MQ)作为一种重要的中间件,扮演着连接不同服务、实现异步通信和消息解耦的关键角色。Apache RocketMQ作为一款高性能的分布式消息中间件,广泛应用于实时数据流处理、日志流处理等场景。为了保证消息的可靠性,RocketMQ引入了一种称为“刷盘”的机制,将消息从内存写入到磁盘中,确保消息持久化。本文将从底层原理、业务场景、概念、功能点等方面深入解析RocketMQ的文件刷盘机制,并使用Java模拟实现类似的功能。
40 3
|
1月前
|
存储
文件太大不能拷贝到U盘怎么办?实用解决方案全解析
当我们试图将一个大文件拷贝到U盘时,却突然跳出提示“对于目标文件系统目标文件过大”。这种情况让人感到迷茫,尤其是在急需备份或传输数据的时候。那么,文件太大为什么会无法拷贝到U盘?又该如何解决?本文将详细分析这背后的原因,并提供几个实用的方法,帮助你顺利将文件传输到U盘。
|
2月前
|
XML 数据格式
HTML 实例解析
本文介绍了HTML中常见元素的使用方法,包括`&lt;p&gt;`、`&lt;body&gt;`和`&lt;html&gt;`等。详细解析了这些元素的结构和作用,并强调了正确使用结束标签的重要性。此外,还提到了空元素的使用及大小写标签的规范。
|
2月前
|
缓存 Java 程序员
Map - LinkedHashSet&Map源码解析
Map - LinkedHashSet&Map源码解析
76 0
|
2月前
|
算法 Java 容器
Map - HashSet & HashMap 源码解析
Map - HashSet & HashMap 源码解析
62 0

推荐镜像

更多
下一篇
DataWorks