Node.js实现修改文件字符集功能的具体过程

 更新时间:2024年08月15日 09:12:05   作者:子洋  
在日常生活、工作中,我们经常会遇到需要处理不同编码格式的文件,有时,在尝试打开这些文件时会遇到乱码,原因通常是文件的编码与我们使用的文本编辑器或编程语言的默认编码不匹配,这篇文章将介绍Node.js修改文件字符集的实现思路和具体实现过程

前言

在日常生活、工作中,我们经常会遇到需要处理不同编码格式的文件。有时,在尝试打开这些文件时会遇到乱码,原因通常是文件的编码与我们使用的文本编辑器或编程语言的默认编码不匹配。这种情况尤其常见于一些历史遗留的文件或从不同系统中导出的数据。

手动处理这种问题不仅耗时,而且容易出错。如果文件数量较多,更是令人头疼。为了解决这个问题,我编写了一个脚本,自动化地将大量文件的编码格式转换为常用的 UTF-8。这篇文章将介绍该脚本的实现思路和具体实现过程,希望对遇到类似问题的朋友有所帮助。

实现思路

实现的思路其实非常简单:递归读取指定文件夹下的所有文件,然后检测每个文件的编码格式,将其转换为 UTF-8 并写回文件。通过这种方式,我们能够确保所有文件都统一为 UTF-8 编码,从而避免乱码问题。

具体实现

我们使用 Node.js 来实现这个功能。Node.js 提供了丰富的文件系统操作 API,以及强大的第三方库来简化编码转换等操作。下面是具体的实现过程。

递归读取文件

首先,我们需要递归读取指定目录下的所有文件。这可以通过 Node.js 提供的 fs.readdir 方法来实现。这里有两个很有用的配置属性:

  • withFileTypes - 当设置为 true 时,readdir 方法返回的将是 fs.Dirent 对象数组。这个对象提供了关于文件类型的信息,比如是否为目录等。
  • recursive - 当设置为 true 时,可以递归读取目录及其子目录下的所有文件。

通过这两个属性,我们可以轻松地获取指定目录下的所有文件路径,并判断它们是否是文件夹。下面是具体代码实现:

/**
 * 递归获取文件夹下所有文件
 * @param {string} path 
 * @returns 
 */
async function readAllBook(path) {
  let filesList = [];

  const files = await readdir(path, { withFileTypes: true, recursive: true });
  for (const file of files) {
    if (file.isDirectory()) continue
    const filePath = join(file.path, file.name);
    filesList.push(filePath);
  }

  return filesList;
}

调用这个函数后,我们可以获得指定目录下所有文件的路径,方便后续处理。

获取字符集编码

尝试读取文件内容

通常在使用 Node.js 读取文件时,我们会指定编码方式,比如 utf-8。然而,如果文件的编码格式与我们指定的不一致,就会出现乱码。

await readFile('book/book1.txt', { encoding: 'utf-8' }).then(async (data) => {
	console.log(data);
})

如果文件本身并不是 utf-8 编码的,读取时就可能会出现乱码。为了正确读取文件,我们需要首先检测它的编码格式。

Node 支持的字符编码

在处理文件编码的时候,了解 Node.js 支持的字符编码对我们来说还是挺重要的。Node.js 提供了一系列的编码选项,可以在 Buffer 和字符串之间进行转换,以下是 Node.js 支持的主要字符编码和它们的用途。

常用字符编码

  • utf8(别名:utf-8: 这是最常用的编码格式,支持多字节编码的 Unicode 字符。它能很好地处理包含各种字符的文本文件,是我们转换目标的首选编码。

  • utf16le(别名:utf-16le: 这个编码格式也支持多字节编码的 Unicode 字符,但与 utf8 不同,utf16le 使用 2 或 4 个字节来编码每个字符。它常用于处理东亚字符集。

  • latin1: 这个编码代表 ISO-8859-1,只支持 U+0000U+00FF 范围内的 Unicode 字符。它使用单字节编码,对于某些老旧系统或文件,这种编码可能依然常见。

二进制编码

在处理一些需要编码二进制数据为字符串,或从字符串解码二进制数据的场景时,以下编码格式也可能会用到:

  • base64: 这是最常见的二进制到文本的编码方式,常用于编码图像、音频文件等。

  • hex: 将每个字节编码为两个十六进制字符,常用于处理加密数据。

旧版字符编码

  • ascii: 这个编码仅适用于 7 位 ASCII 数据。在现代应用中通常很少用到,因为它无法处理非英语字符。

  • binary: 这是 latin1 的别名,用于处理简单的二进制数据。

  • ucs2ucs-2: 这些是 utf16le 的别名,曾经用于处理不支持 U+FFFF 以上字符的场景。

jschardet

jschardet 是一个字符编码的检测器,可以用来检测文本文件或数据流的字符编码的工具。它的工作原理就是通过分析文本中的字节模式,尝试匹配已知的编码方式。支持 20 多种字符编码,但要注意的是检测出来的结果不能保证百分之百的准确。

我们使用 npm i jschardet 安装 jschardet 之后,就可以使用 detect 方法获取字符编码

import jschardet from 'jschardet';

await readFile('book/book1.txt').then(async (data) => {
  console.log(jschardet.detect(data));
})

这个方法会返回一个对象:encodingconfidenceencoding 是检测的编码,confidence 是这个检测结果的置信度。

每个检测器都会根据它的分析给出一个置信度(Confidence Level),置信度最高的编码就会被选中。就像我们之前说的,因为很多编码很相似,所以这个检测并不是百分之百准确,但 chardet 设计得比较聪明,通常能给出一个比较靠谱的结果。

转换字符集编码

现在我们拿到了文件内容的字符编码,需要一个转换器将内容转换为 utf-8, 这时我们需要引入一个新的库 iconv-lite

iconv-lite 是一个用于 Node.js 的轻量级字符编码转换库。它允许你在 Node.js 应用程序中进行字符编码的转换和处理,特别是处理非 UTF-8 编码的数据。与其他类似的库相比,iconv-lite 更加轻便,因为它不依赖外部的 C 库或者原生模块,完全用纯 JavaScript 实现。

import iconv from 'iconv-lite';

await readFile('book/book1.txt').then(async (data) => {
  const { encoding } = jschardet.detect(data);
  console.log(iconv.decode(data, encoding));
})

通过以上代码,我们可以将文件内容正确地解码为 UTF-8 格式,并输出到控制台。

获取到转码内容的后,我们就可以遍历之前获取的文件列表,全部进行转码重新写入文件了,这个步骤很简单,不单独进行讲解了,可以直接参考下面的完整代码。

完整代码

import { readdir, readFile, writeFile } from 'node:fs/promises';
import { join } from 'node:path';

import iconv from 'iconv-lite';
import jschardet from 'jschardet';

/**
 * 递归获取文件夹下所有文件
 * @param {string} path 
 * @returns 
 */
async function readAllBook(path) {
  let filesList = [];

  const files = await readdir(path, { withFileTypes: true, recursive: true });
  for (const file of files) {
    if (file.isDirectory()) continue
    const filePath = join(file.path, file.name);
    filesList.push(filePath);
  }

  return filesList;
}

readAllBook('./book').then(async (files) => {
  console.log('文件重写开始,请稍候...');
  for (const file of files) {
    await readFile(file).then(async (data) => {
      // 获取读取的内容编码
      const charset = jschardet.detect(data)
      // 转换内容编码
      const fileContent = iconv.decode(data, charset.encoding || 'GB2312')
      // 重新写回文件
      await writeFile(file, fileContent, { encoding: 'utf-8' }).catch((err) => {
        console.log(file + '文件写入失败', err);
      });
    });
  }
  console.log('文件重写完成!');
});

结语

通过使用 Node.js 和一些实用的第三方库,我们可以快速有效地解决这个问题。希望这篇文章能够帮助你更好地理解文件编码转换,并应用到实际生活和工作中。

以上就是Node.js实现修改文件字符集功能的具体过程的详细内容,更多关于Node.js修改文件字符集的资料请关注脚本之家其它相关文章!

相关文章

  • Node.js中的npm单独与批量升级依赖包的方式超详细讲解

    Node.js中的npm单独与批量升级依赖包的方式超详细讲解

    npm outdated仅检查所有已安装包的依赖关系,并将当前版本远程仓库中的最新版本进行对比,不会升级,这篇文章主要介绍了Node.js中的npm单独与批量升级依赖包的方式超详细讲解,需要的朋友可以参考下
    2024-02-02
  • Node使用koa2实现一个简单JWT鉴权的方法

    Node使用koa2实现一个简单JWT鉴权的方法

    这篇文章主要介绍了Node使用koa2实现一个简单JWT鉴权的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01
  • Node.js 应用跑得更快 10 个技巧

    Node.js 应用跑得更快 10 个技巧

    Node.js 受益于它的事件驱动和异步的特征,已经很快了。本文将介绍 10 条,经过检验得知可大大提高 Node 应用的技巧。废话不多说,让我们逐条来看看
    2016-04-04
  • nodejs中request库使用HTTPS代理的方法

    nodejs中request库使用HTTPS代理的方法

    这篇文章主要介绍了nodejs中request库使用HTTPS代理的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-04-04
  • Node.js文件编码格式的转换的方法

    Node.js文件编码格式的转换的方法

    这篇文章主要介绍了Node.js文件编码格式的转换的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-04-04
  • Nodejs访问网络并解析返回的json的实现方法

    Nodejs访问网络并解析返回的json的实现方法

    本文主要介绍了Nodejs访问网络并解析返回的json的实现方法,文中根据实例编码详细介绍的十分详尽,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • 在Node.js中实现视频收藏功能

    在Node.js中实现视频收藏功能

    在构建视频分享平台时,视频的收藏功能是用户互动的重要组成部分,本文将介绍如何在Node.js应用中实现视频收藏功能,包括数据模型的创建、业务逻辑的实现以及接口的验证测试,需要的朋友可以参考下
    2024-04-04
  • node.js中的buffer.Buffer.byteLength方法使用说明

    node.js中的buffer.Buffer.byteLength方法使用说明

    这篇文章主要介绍了node.js中的buffer.Buffer.byteLength方法使用说明,本文介绍了buffer.Buffer.byteLength的方法说明、语法、接收参数、使用实例和实现源码,需要的朋友可以参考下
    2014-12-12
  • node.js正则表达式获取网页中所有链接的代码实例

    node.js正则表达式获取网页中所有链接的代码实例

    这篇文章主要介绍了node.js正则表达式获取网页中所有链接的代码实例,使用正则表达式实现,需要的朋友可以参考下
    2014-06-06
  • 用node开发并发布一个cli工具的方法步骤

    用node开发并发布一个cli工具的方法步骤

    这篇文章主要介绍了用node开发并发布一个cli工具的方法步骤,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-01-01

最新评论