在node.js应用程序中读取文件时出现奇怪的unicode字符

问题描述 投票:0回答:5

我正在尝试编写一个节点应用程序,该应用程序读取一组文件,将它们分成行,并将这些行放入数组中。很简单。除了我正在使用的一些 SQL 文件之外,它适用于相当多的文件。由于某种原因,当我分割行时,我似乎得到了某种 unicode 输出。该应用程序看起来像这样:

fs = require("fs");
var data = fs.readFileSync("test.sql", "utf8");
console.log(data);
lines = data.split("\n");
console.log(lines);

输入文件看起来像这样:

use whatever
go

输出如下所示:

��use whatever
go

[ '��u\u0000s\u0000e\u0000 \u0000w\u0000h\u0000a\u0000t\u0000e\u0000v\u0000e\u0000r\u0000',
  '\u0000g\u0000o\u0000',
  '\u0000' ]

如您所见,文件开头有某种无法识别的字符。读入数据后直接输出,除了这个字符之外,看起来都还好。但是,如果我尝试将其分成几行,我会得到所有这些类似 unicode 的字符。基本上都是以“\u0000”开头的所有实际字符。

我不知道这里发生了什么,但它似乎与文件本身中的字符有关。如果我将文件的文本复制并粘贴到另一个新文件中,并在新文件上运行应用程序,则它可以正常工作。我认为导致此问题的任何原因都在复制和粘贴过程中被删除。

javascript node.js unicode utf-16 utf
5个回答
26
投票

您的文件采用 UTF-16 Little Big Endian,而不是 UTF-8。

var data = fs.readFileSync("test.sql", "utf16le"); //Not sure if this eats the BOM

不幸的是node.js仅支持UTF-16 Little Endian或UTF-16LE(通过阅读文档无法确定,它们之间有细微的区别;即UTF-16LE不使用BOM),所以你必须使用iconv 或以其他方式将文件转换为 UTF-8。

示例:

var Iconv  = require('iconv').Iconv,
    fs = require("fs");

var buffer = fs.readFileSync("test.sql"),
    iconv = new Iconv( "UTF-16", "UTF-8");

var result = iconv.convert(buffer).toString("utf8");

2
投票

这可能是

BOM
(字节顺序标记)吗?确保保存的文件不带
BOM
或包含代码以去除
BOM

BOM
通常在文本编辑器中不可见。

我知道 Notepad++ 有一个功能,您可以轻松地从文件中删除

BOM
Encoding > Encode in UTF-8 without BOM


1
投票

我在 Windows 命令提示符中执行了以下操作来转换字节序:

type file.txt > file2.txt

0
投票

使用精简版的Iconv-lite

var result= "";
var iconv = require('iconv-lite');
var stream = fs.createReadStream(sourcefile)
    .on("error",function(err){
        //handle error
    })
    .pipe(iconv.decodeStream('win1251'))
    .on("error",function(err){
        //handle error
    })
    .on("data",function(data){
        result += data;
    })
    .on("end",function(){
       //use result
    });

0
投票
var data = readFileSync('filename.xml', 'utf8');
data.replaceAll('\ufffd', '')

为我工作了 Node v19.9.0

© www.soinside.com 2019 - 2024. All rights reserved.