我正在尝试编写一个节点应用程序,该应用程序读取一组文件,将它们分成行,并将这些行放入数组中。很简单。除了我正在使用的一些 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”开头的所有实际字符。
我不知道这里发生了什么,但它似乎与文件本身中的字符有关。如果我将文件的文本复制并粘贴到另一个新文件中,并在新文件上运行应用程序,则它可以正常工作。我认为导致此问题的任何原因都在复制和粘贴过程中被删除。
您的文件采用 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");
这可能是
BOM
(字节顺序标记)吗?确保保存的文件不带 BOM
或包含代码以去除 BOM
。
BOM
通常在文本编辑器中不可见。
我知道 Notepad++ 有一个功能,您可以轻松地从文件中删除
BOM
。 Encoding > Encode in UTF-8 without BOM
。
我在 Windows 命令提示符中执行了以下操作来转换字节序:
type file.txt > file2.txt
使用精简版的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
});
var data = readFileSync('filename.xml', 'utf8');
data.replaceAll('\ufffd', '')
为我工作了 Node v19.9.0