当前位置:首页 > 编程语言 > 正文内容

了解Node.js文件系统模块 (FS)

a811625532年前 (2024-01-06)编程语言13

JavaScript 长期以来一直是更流行的脚本语言之一,但在很长一段时间内,它并不是服务器端后端应用程序开发的更佳选择。后来出现了 Node.js,它用于创建使用 JavaScript 编程语言构建的服务器端、事件驱动的轻量级应用程序。

是一种开源 JavaScript 运行时,可在任何顶级操作系统(Windows、Mac、Linux)上免费下载和安装。近年来,Node.js 越来越受到的青睐,也为寻求一技之长的 JavaScript 开发人员提供了许多。

在本文中,我们将学习使用 Node.js 管理文件系统。使用 Node.js API 与文件系统交互并执行许多复杂的操作并不费力,了解如何使用这些 API 将提高您的工作效率。

了解 Node.js 文件系统的先决条件

首要前提是在操作系统上安装 Node.js。Node.js 的运行不需要任何复杂的硬件,因此很容易下载并在计算机上。

如果您还具备 的基础知识,将有助于处理 Node.js 模块,如文件系统(也称为 “FS “或 “fs”)。对 JavaScript 函数、回调函数和承诺的高级理解将。

Node.js 文件系统模块

处理文件和目录是全栈应用程序的基本需求之一。您的用户可能希望将图片、简历或其他文件上传到服务器。同时,您的应用程序可能需要读取配置文件、移动文件,甚至以编程方式更改文件权限。

Node.js 文件系统模块涵盖了所有这些功能。它提供了多个与文件系统无缝交互的 API。大多数 API 都可通过选项和标志进行自定义。您还可以使用它们执行同步和异步文件操作。

在深入了解文件系统模块之前,让我们先来了解一下 Node.js 模块。

Node.js 模块

Node.js 模块是一组作为 API 提供给用户程序使用的功能。例如,你可以使用 fs 模块与文件系统交互。同样,http 模块利用其功能创建服务器和进行更多操作。Node.js 提供了大量模块,可为您抽象出许多底层功能。

您也可以 *** 自己的模块。在 Node.js 14 及以后的版本中,您可以通过两种方式创建和使用 Node.js 模块: Common *** (C *** ) 和 E *** (M *** ) 模块。我们将在本文中看到的所有示例都采用 C *** 风格。

在 Node.js 中处理文件

处理文件涉及对文件和目录(文件夹)的各种操作。现在,我们将通过示例源代码了解这些操作中的每一种。请打开您最喜欢的,边读边试。

首先,在源文件中导入 fs 模块,以便开始使用文件系统 *** 。在 C *** 风格中,我们使用 require *** 从模块中导入 *** 。因此,要导入并使用 fs 模块 *** ,可以这样做

const { writeFile } = require('fs/promises');

另外,请注意我们从 fs/promises 包中导入了 writeFile *** 。我们希望使用 promisified *** ,因为它们是最新的 *** ,而且易于使用 async/await 关键字和较少的代码。其他替代 *** 有同步 *** 和回调函数,我们稍后会看到。

如何创建和写入文件

创建和写入文件有三种 *** :

  1. 使用 writeFile ***
  2. 使用 appendFile ***
  3. 使用 openFile ***

这些 *** 接受文件路径和数据作为要写入文件的内容。如果文件存在,它们会替换文件中的内容。否则,它们会用这些内容创建一个新文件。

1. 使用 writeFile ***

下面的代码片段展示了 writeFile *** 的用法。首先,使用下面的代码片段创建一个名为 createFile.js 的文件:

const { writeFile } = require('fs/promises');
async function writeToFile(fileName, data) {
try {
await writeFile(fileName, data);
console.log(`Wrote data to ${fileName}`);
} catch (error) {
console.error(`Got an error trying to write the file: ${error.message}`);
}
}

请注意,我们使用 await 关键字来调用该 *** ,因为它会返回一个 JavaScript 承诺。成功的承诺将创建/写入文件。我们有一个 try-catch 块来处理承诺被拒绝时的错误。

现在我们可以调用 writeToFile 函数了:

writeToFile('friends.txt', 'Bob');

然后,打开命令提示符或终端,使用以下命令运行上述程序:

node createFile.js

它将创建一个名为 friends.txt 的新文件,其中一行简单地写道:

Bob

2. 使用 appendFile ***

顾名思义,该 *** 的主要用途是追加和编辑文件。不过,你也可以使用相同的 *** 来创建文件。

请看下面的函数。我们使用带有 w 标志的 appendFile *** 来写入文件。追加文件的默认标志是 a

const { appendFile} = require('fs/promises');
async function appendToFile(fileName, data) {
try {
await appendFile(fileName, data, { flag: 'w' });
console.log(`Appended data to ${fileName}`);
} catch (error) {
console.error(`Got an error trying to append the file: {error.message}`);
}
}

现在,您可以像这样调用上述函数:

appendToFile('activities.txt', 'Skiing');

接下来,您可以在 Node.js 环境中使用 node 命令执行代码,就像我们之前看到的那样。这将创建一个名为 activities.txt 的文件,其中包含 Skiing 的内容。

3. 使用 open ***

我们要学习的最后一种创建和写入文件的 *** 是 open。你可以使用 w (”写”)标记打开文件:

const { open} = require('fs/promises');
async function openFile(fileName, data) {
try {
const file = await open(fileName, 'w');
await file.write(data);
console.log(`Opened file ${fileName}`);
} catch (error) {
console.error(`Got an error trying to open the file: {error.message}`);
}
}

现在调用 openFile 函数:

openFile('tasks.txt', 'Do homework');

使用 node 命令运行脚本后,将创建一个包含初始内容的名为 tasks.txt 的文件:

Do homework

如何读取文件

既然我们已经知道了如何创建和写入文件,那就来学习读取文件内容吧。为此,我们将使用文件系统模块中的 readFile *** 。

用以下代码创建一个名为 readThisFile.js 的文件:

// readThisFile.js
const { readFile } = require('fs/promises');
async function readThisFile(filePath) {
try {
const data = await readFile(filePath);
console.log(data.toString());
} catch (error) {
console.error(`Got an error trying to read the file: {error.message}`);
}
}

现在,让我们通过调用 readThisFile 函数来读取我们创建的所有三个文件:

readThisFile('activities.txt');
readThisFile('friends.txt');
readThisFile('tasks.txt');

最后,使用以下 node 命令执行脚本:

node readThisFile.js

你应该在控制台中看到以下输出:

Skiing
Do homework
Bob

这里有一点需要注意:readFile *** 以异步方式读取文件。这意味着读取文件的顺序和在控制台中打印响应的顺序可能不一致。你必须使用同步版本的 readFile *** 才能按顺序读取文件。稍后我们将在这里看到这一点。

如何重命名文件

要重命名文件,请使用 fs 模块中的 rename *** 。让我们创建一个名为 rename-me.txt 的文件。我们将以编程方式重命名该文件。

用以下代码创建一个名为 renameFile.js 的文件:

const { rename } = require('fs/promises');
async function renameFile(from, to) {
try {
await rename(from, to);
console.log(`Renamed ${from} to ${to}`);
} catch (error) {
console.error(`Got an error trying to rename the file: ${error.message}`);
}
}

你可能已经注意到,重命名 *** 需要两个参数。一个是源文件名,另一个是目标文件名。

现在让我们调用上述函数来重命名文件:

const oldName = "rename-me.txt";
const newName = "renamed.txt";
renameFile(oldName, newName);

像以前一样,使用 node 命令执行脚本文件,重命名文件:

node renameFile.js

如何移动文件

将文件从一个目录移动到另一个目录与重命名文件路径类似。因此,我们可以使用 rename  *** 本身来移动文件。

让我们创建两个文件夹:fromto。然后在 from 文件夹中创建一个名为 move-me.txt 的文件。

接下来,我们将编写代码来移动 move-me.txt 文件。用以下代码段创建一个名为 moveFile.js 的文件:

const { rename } = require('fs/promises');
const { join } = require('path');
async function moveFile(from, to) {
try {
await rename(from, to);
console.log(`Moved ${from} to ${to}`);
} catch (error) {
console.error(`Got an error trying to move the file: ${error.message}`);
}
}

正如你所看到的,我们像以前一样使用 rename *** 。但为什么我们需要从 path 模块(是的,path 是 Node.js 的另一个重要模块)导入 join *** 呢?

join *** 用于将多个指定的路径段连接成一条路径。我们将用它来形成源文件和目标文件名的路径:

const fromPath = join(__dirname, "from", "move-me.txt");
const destPath = join(__dirname, "to", "move-me.txt");
moveFile(fromPath, destPath);

就是这样!如果你执行 moveFile.js 脚本,就会看到 move-me.txt 文件被移动到 to 文件夹。

如何复制文件

我们使用 fs 模块中的 copyFile *** 将文件从源文件复制到目标文件。

请看下面的代码片段:

const { copyFile } = require('fs/promises');
const { join } = require('path');
async function copyAFile(from, to) {
try {
await copyFile(from, to);
console.log(`Copied ${from} to ${to}`);
} catch (err) {
console.error(`Got an error trying to copy the file: ${err.message}`);
}
}

现在,您可以使用以下命令调用上述函数:

copyAFile('friends.txt', 'friends-copy.txt');

它会将 friends.txt 的内容复制到 friends-copy.txt 文件中。

这很好,但如何复制多个文件呢?

您可以使用 Promise.all API 来并行执行多个承诺:

async function copyAll(fromDir, toDir, filePaths) {
return Promise.all(filePaths.map(filePath => {
return copyAFile(join(fromDir, filePath), join(toDir, filePath));
}));
}

现在,您可以提供所有文件路径,以便从一个目录复制到另一个目录:

copyFiles('from', 'to', ['copyA.txt', 'copyB.txt']);

您还可以使用这种 *** 来执行其他操作,如并行移动、写入和读取文件。

如何删除文件

我们使用 unlink 链接的 *** 来删除文件:

const { unlink } = require('fs/promises');
async function deleteFile(filePath) {
try {
await unlink(filePath);
console.log(`Deleted ${filePath}`);
} catch (error) {
console.error(`Got an error trying to delete the file: ${error.message}`);
}
}

请记住,要删除文件,您需要提供文件的路径:

deleteFile('delete-me.txt');

请注意,如果路径是指向另一个文件的符号链接,unlink *** 将取消符号链接,但原始文件将保持不变。稍后我们将进一步讨论符号链接。

如何更改文件权限和所有权

在某些情况下,您可能希望以编程方式更改文件权限。这对于使文件成为只读文件或完全可访问文件非常有用。

我们将使用 chmod *** 来更改文件权限:

const { chmod } = require('fs/promises');
async function changePermission(filePath, permission) {
try {
await chmod(filePath, permission);
console.log(`Changed permission to ${permission} for ${filePath}`);
} catch (error) {
console.error(`Got an error trying to change permission: ${error.message}`);
}
}

我们可以通过文件路径和权限位掩码来更改权限。

下面是将文件权限改为只读的函数调用:

changePermission('permission.txt', 0o400);

与权限类似,你也可以通过编程改变文件的所有权。我们使用 chown *** 来实现这一功能:

const { chown } = require('fs/promises');
async function changeownership(filePath, userId, groupId) {
try {
await chown(filePath, userId, groupId);
console.log(`Changed ownership to ${userId}:${groupId} for ${filePath}`);
} catch (error) {
console.error(`Got an error trying to change ownership: ${error.message}`);
}
}

然后,我们使用文件路径、用户 ID 和组 ID 调用该函数:

changeOwnership('ownership.txt', 1000, 1010);

如何创建符号链接

是一个文件系统概念,用于创建指向文件或文件夹的链接。我们创建符号链接是为了在文件系统中创建指向目标文件/文件夹的快捷方式。Node.js  filesystem 模块提供了创建符号链接的 symlink *** 。

要创建符号链接,我们需要传递目标文件路径、实际文件路径和类型:

const { symlink } = require('fs/promises');
const { join } = require('path');
async function createSymlink(target, path, type) {
try {
await symlink(target, path, type);
console.log(`Created symlink to ${target} at ${path}`);
} catch (error) {
console.error(`Got an error trying to create the symlink: ${error.message}`);
}
}

我们可以用:

createSymlink('join(__dirname, from, symMe.txt)', 'symToFile', 'file');

在这里,我们创建了一个名为 symToFile 的符号链接。

如何查看文件的更改

你知道可以查看文件的更改吗?这是一种监控更改和事件的好 *** ,尤其是在你意想不到的时候。你可以捕捉和审核这些变化,以便日后查看。

watch *** 是观察文件变化的更佳 *** 。还有一种名为 watchFile 的替代 *** ,但其性能不如 watch *** 。

到目前为止,我们已经使用了带有 async/await 关键字的文件系统模块 *** 。让我们通过这个例子看看 callback 函数的用法。

watch *** 接受文件路径和回调函数作为参数。每当文件发生活动时,回调函数就会被调用。

我们可以利用 event 参数获取有关活动的更多信息:

const fs = require('fs');
function watchAFile(file) {
fs.watch(file, (event, filename) => {
console.log(`${filename} file Changed`);
});
}

通过传递文件名给 watch 来调用函数:

watchAFile('friends.txt');

现在,我们将自动捕获 friends.txt 文件中的任何活动。

在 Node.js 中处理目录(文件夹)

现在我们来学习如何对目录或文件夹执行操作。重命名、移动和复制等许多操作与我们在文件中看到的类似。不过,一些特定的 *** 和操作只能在目录上使用。

如何创建目录

我们使用 mkdir *** 创建目录。需要将目录名称作为参数传递:

const { mkdir } = require('fs/promises');
async function createDirectory(path) {
try {
await mkdir(path);
console.log(`Created directory ${path}`);
} catch (error) {
console.error(`Got an error trying to create the directory: ${error.message}`);
}
}

现在,我们可以使用目录路径调用 createDirectory 函数:

createDirectory('new-directory');

这将创建一个名为 new-directory 的目录。

如何创建临时目录

临时目录不是常规目录。它们对操作系统有特殊意义。你可以使用 mkdtemp() *** 创建临时目录。

让我们在操作系统的临时目录中创建一个临时文件夹。我们从 os 模块的 tmpdir() *** 中获取临时目录位置的信息:

const { mkdtemp } = require('fs/promises');
const { join } = require('path');
const { tmpdir } = require('os');
async function createTemporaryDirectory(fileName) {
try {
const tempDirectory = await mkdtemp(join(tmpdir(), fileName));
console.log(`Created temporary directory ${tempDirectory}`);
} catch (error) {
console.error(`Got an error trying to create the temporary directory: ${error.message}`);
}
}

现在,让我们调用带有目录名的函数来创建目录:

createTemporaryDirectory('node-temp-file-');

请注意,Node.js 会在创建的临时文件夹名称末尾添加六个随机字符,以保持其唯一性。

如何删除目录

您需要使用 rmdir() *** 来删除目录:

const { rmdir } = require('fs/promises');
async function deleteDirectory(path) {
try {
await rmdir(path);
console.log(`Deleted directory ${path}`);
} catch (error) {
console.error(`Got an error trying to delete the directory: ${error.message}`);
}
}

接下来,通过传递要删除的文件夹的路径来调用上述函数:

deleteDirectory('new-directory-renamed');

同步与异步 API

到目前为止,我们已经看到了很多文件系统 *** 的示例,所有这些 *** 都是异步使用的。不过,您可能需要同步处理某些操作。

同步操作的一个例子就是一个接一个地读取多个文件。 fs 模块有一个名为 readFileSync() 的 *** 来完成这一操作:

const { readFileSync } = require('fs');
function readFileSynchronously(path) {
try {
const data = readFileSync(path);
console.log(data.toString());
} catch (error) {
console.error(error);
}
}

请注意,”fs/promises” 软件包中不需要 readFileSync() *** 。这是因为该 *** 不是异步的。因此,调用上述函数时可以使用

readFileSynchronously('activities.txt');
readFileSynchronously('friends.txt');
readFileSynchronously('tasks.txt');

在这种情况下,将按照调用函数的顺序读取上述所有文件。

Node.js 文件系统模块为其他操作(如读取操作)提供了同步 *** 。请根据需要明智使用。异步 *** 对并行执行更有帮助。

处理错误

任何程序员都知道,在执行文件或目录操作时,必须的准备。如果找不到文件,或者没有写入文件的权限,该怎么办?在很多情况下,您都可能会遇到错误。

您应该始终在 *** 调用周围使用 try-catch 块。这样,如果发生错误,控制将转到 catch 块,你可以在那里查看并处理错误。你可能已经注意到,在上面的所有示例中,我们都使用了 try-catch 块来处理遇到的错误。

小结

让我们回顾一下本教程中涉及的要点:

  • Node.js 文件系统 (fs) 模块有许多 *** 可帮助完成许多底层任务。
  • 您可以执行各种文件操作,如创建、写入、重命名、复制、移动、删除等。
  • 还可以执行创建、临时目录、移动等多种目录操作。
  • 所有 *** 都可以使用 JavaScript 承诺或回调函数异步调用。
  • 如果需要,也可以同步调用这些 *** 。
  • 与同步 *** 相比,异步 *** 更受青睐。
  • 每次与 *** 交互时,使用 try-catch 块处理错误。

现在,我们已经熟悉了 Node.js 文件系统,你应该对它的来龙去脉有所了解。如果你想进一步加强你的专业知识,你可能想了解一下 ,这也是学习 Node.js 模块的自然进展。流是处理信息交换的有效 *** ,包括 *** 调用、文件读/写等。

您可以在 中找到本文使用的所有源代码。

您是否计划在下一个项目中使用 Node.js?请在下面的评论区告诉我们您选择 Node.js 的原因。

扫描二维码推送至手机访问。

版权声明:本文由2345好导航站长资讯发布,如需转载请注明出处。

本文链接:http://2345hao.cn/blog/index.php/post/8164.html

分享给朋友:

“了解Node.js文件系统模块 (FS)” 的相关文章

宝塔面板教程之安装及常见问题篇

宝塔面板教程之安装及常见问题篇

宝塔面板现在已经成为国内许多站长必备的服务器管理必备工具。相比直接使用SSH+FTP来管理服务器,宝塔面板可以提供可视化管理,包括文件管理、数据库管理、数据备份、SSL配置等等。 如果你希望更简单高效地管理您的网站及服务器,宝塔面板是不错的选择。下面是一些宝塔面板安装及常见问题:...

静态与动态IP地址有何区别?

静态与动态IP地址有何区别?

每台连接到Internet的计算机都有一个Internet协议 (IP) 地址。但是,并非所有IP地址的外观或行为都相同。 如果您使用计算机网络或服务器,了解动态IP和静态IP之间的区别至关重要。通过详细了解每个协议,您可以选择最适合您需求的解决方案。 在本文中,我们将讨论静态和动态IP之间...

宝塔面板教程之监控管理篇

宝塔面板教程之监控管理篇

宝塔面板另外一个特质是,你无需通过Linux命令行来查看服务器各项指标状况,即可以阿里云服务器类似的可视化图表,查看资源使用、负载、CPU占用及内容使用百分比等指标。 默认监控是关闭,有需要的,可以开启,监控数据默认保存30天,可以自行修改,默认监控数据保存在日志,可手动清理该日志。 监控管理,...

深入了解什么是函数即服务 (FaaS)

深入了解什么是函数即服务 (FaaS)

您可能听说过SaaS,您可能听说过PaaS和IaaS,但您听说过函数即服务 (FaaS) 吗? FaaS市场正在快速增长。根据Allied Market Research的数据,2018年市场价值 。预计到2026年,这一数字将增长到240亿美元——这意味着该行业将从2020年到2026年以2...

PHP 8.2年内将发布,一起来看看都有什么新特征

PHP 8.2年内将发布,一起来看看都有什么新特征

PHP 8.2预计将于今年11月发布,最新的稳定版本是PHP 8.1.5。虽然现在还为时过早,但对更新的接受程度参差不齐。 但是,知道会发生什么可以帮助您。通过了解新功能和不推荐使用的功能,您可以了解更新可能如何影响开发。这些知识还可以帮助您为最终发布做好准备。 在这篇文章中,我们将回顾最新...

Cloudflare即将完全弃用Host API集成

Cloudflare即将完全弃用Host API集成

Cloudflare已宣布弃用HOST API集成,这将影响Cloudflare的传统主机和经销商合作伙伴。 Cloudflare弃用HOST API Cloudflare Legacy Host API将于2022年11月1日正式被弃用。Cloudflare表示,由于支持和维护程序...