13

我正在尝试编写一个节点应用程序,它读取一组文件,将它们分成几行,然后将这些行放入一个数组中。很简单。它适用于很多文件,除了我正在使用的一些 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”开头的实际字符。

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

4

4 回答 4

25

您的文件是 UTF-16 Little大的字节序,而不是 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");
于 2013-01-18T17:14:53.610 回答
2

这可能是BOM(字节顺序标记)吗?确保您保存文件时不使用BOM或包含代码以去除BOM.

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

我知道 Notepad++ 有一个功能,您可以轻松地BOM从文件中删除 a。Encoding > Encode in UTF-8 without BOM.

于 2013-01-18T16:37:48.847 回答
1

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

type file.txt > file2.txt
于 2018-07-16T04:12:40.000 回答
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
    });
于 2017-05-18T09:22:30.273 回答