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

简介: 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()

用法基本类似。

目录
相关文章
|
数据采集 机器学习/深度学习 人工智能
静态长效代理IP利用率瓶颈解析与优化路径
在信息化时代,互联网已深度融入社会各领域,HTTP动态代理IP应用广泛,但静态长效代理IP利用率未达百分百,反映出行业结构性矛盾。优质IP资源稀缺且成本高,全球IPv4地址分配殆尽,高质量IP仅占23%。同时,代理服务管理存在技术瓶颈,如IP池更新慢、质量监控缺失及多协议支持不足。智能调度系统也面临风险预判弱、负载均衡失效等问题。未来需构建分布式IP网络、引入AI智能调度并建立质量认证体系,以提升资源利用率,推动数字经济发展。
392 2
|
JSON Shell Linux
dockerfile 用法全解析
Dockerfile指令简介:`FROM`基于Alpine镜像;`WORKDIR`设置工作目录;`COPY`复制文件;`ADD`支持URL;`RUN`运行命令;`CMD`容器启动时执行;`ENTRYPOINT`与`CMD`组合执行;`EXPOSE`声明端口;`VOLUME`映射文件;`ENV`设置环境变量;`ARG`构建参数;`LABEL`元数据;`ONBUILD`触发命令;`STOPSIGNAL`停止信号;`HEALTHCHECK`健康检查;`SHELL`默认Shell。Alpine仅5M,小巧高效。
431 4
dockerfile 用法全解析
|
Dart 安全 编译器
Flutter结合鸿蒙next 中数据类型转换的高级用法:dynamic 类型与其他类型的转换解析
在 Flutter 开发中,`dynamic` 类型提供了灵活性,但也带来了类型安全性问题。本文深入探讨 `dynamic` 类型及其与其他类型的转换,介绍如何使用 `as` 关键字、`is` 操作符和 `whereType&lt;T&gt;()` 方法进行类型转换,并提供最佳实践,包括避免过度使用 `dynamic`、使用 Null Safety 和异常处理,帮助开发者提高代码的可读性和可维护性。
638 1
|
缓存 API 网络架构
Nuxt Kit API :路径解析工具
【9月更文挑战第20天】在 Nuxt Kit API 中,路径解析工具如 `resolvePath()`、`joinPaths()` 和 `relativePath()` 帮助开发者高效处理应用路径,确保资源准确加载,并支持动态路由与组件导入。这些工具提升了应用的灵活性和可扩展性,同时需注意路径准确性、跨平台兼容性和性能优化,以提升用户体验。
268 12
|
安全 网络安全 开发工具
深入探索Git:全面解析Git的用法与最佳实践
深入探索Git:全面解析Git的用法与最佳实践
436 2
|
存储 JSON JavaScript
学习node.js十三,文件的上传于下载
学习node.js十三,文件的上传于下载
|
开发者 图形学 API
从零起步,深度揭秘:运用Unity引擎及网络编程技术,一步步搭建属于你的实时多人在线对战游戏平台——详尽指南与实战代码解析,带你轻松掌握网络化游戏开发的核心要领与最佳实践路径
【8月更文挑战第31天】构建实时多人对战平台是技术与创意的结合。本文使用成熟的Unity游戏开发引擎,从零开始指导读者搭建简单的实时对战平台。内容涵盖网络架构设计、Unity网络API应用及客户端与服务器通信。首先,创建新项目并选择适合多人游戏的模板,使用推荐的网络传输层。接着,定义基本玩法,如2D多人射击游戏,创建角色预制件并添加Rigidbody2D组件。然后,引入网络身份组件以同步对象状态。通过示例代码展示玩家控制逻辑,包括移动和发射子弹功能。最后,设置服务器端逻辑,处理客户端连接和断开。本文帮助读者掌握构建Unity多人对战平台的核心知识,为进一步开发打下基础。
1286 0
|
前端开发 JavaScript UED
axios取消请求CancelToken的原理解析及用法示例
axios取消请求CancelToken的原理解析及用法示例
1733 0
|
缓存 资源调度 JavaScript
npx与npm的差异解析,以及包管理器yarn与Node版本管理工具nvm的使用方法详解
npx与npm的差异解析,以及包管理器yarn与Node版本管理工具nvm的使用方法详解
2734 0

热门文章

最新文章

推荐镜像

更多
  • DNS