当前位置:首页>WordPress资讯>了解Node.js文件系统模块 (FS)

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

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

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

Node.js 是一种开源 JavaScript 运行时,可在任何顶级操作系统(Windows、Mac、Linux)上免费下载和安装。近年来,Node.js 越来越受到应用程序创建者的青睐,也为寻求一技之长的 JavaScript 提供了许多新的就业机会。

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

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

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

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

Node.js 文件系统模块

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

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

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

Node.js 模块

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

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

在 Node.js 中处理文件

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

首先,在源文件中导入 fs 模块,以便开始使用文件系统方法。在 CJS 风格中,我们使用 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);

符号链接(也称 symlink)是一个文件系统概念,用于创建指向文件或文件夹的链接。我们创建符号链接是为了在文件系统中创建指向目标文件/文件夹的快捷方式。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?请在下面的评论区告诉我们您选择 Node.js 的原因。

原文地址:https://www.wbolt.com/nodejs-fs.html

WordPress资讯

Postgres列出数据库和表的实用教程

2024-1-22 1:15:28

WordPress资讯

如何用Python构建自己的OCR API

2024-1-22 1:15:30

个人中心
今日签到
有新私信 私信列表
搜索