Как преобразовать файл UTF16 в файл UTF8 в nodejs

У меня есть файл xml, закодированный в UTF16, и я хотел бы преобразовать его в UTF8, чтобы обработать его. Если я использую эту команду:

iconv -f UTF-16 -t UTF-8 file.xml > converted_file.xml

Файл преобразован правильно, и я могу его обработать. Я хочу сделать то же самое в nodejs.

В настоящее время у меня есть буфер моего файла, и я перепробовал все, что мог придумать и что смог найти в Интернете, но безуспешно.

Вот несколько примеров того, что я пробовал до сих пор:

content = new Buffer((new Buffer(content, 'ucs2')).toString('utf8'));

Я также пытался использовать эти функции:

http://jonisalonen.com/2012/from-utf-16-to-utf-8-in-javascript/ https://stackoverflow.com/a/14601808/1405208

Первый ничего не меняет, а ссылки дают мне только китайские иероглифы.


person Julien Fouilhé    schedule 18.11.2015    source источник


Ответы (2)


Хотя ответ выше меня - лучший ответ на заданный вопрос. Я надеюсь, что этот ответ поможет некоторым людям, которым нужно прочитать файл как двоичную строку:

const reader = new FileReader();
reader.readAsBinaryString(this.fileToImport);

В моем случае файл был в utf-16, и я попытался прочитать его в XLSX:

const wb = XLSX.read(bstr, { type: "binary" });

Объединив обе приведенные выше ссылки, я сначала удалил первые два символа, которые сигнализировали, что это UTF-16 (0xFFFE), а затем использовал эту ссылку для создания правильного числа (но я думаю, что на самом деле она обеспечивает кодировку UTF-7) https://stackoverflow.com/a/14601808/1405208

Наконец, я применил вторую ссылку, чтобы получить правильный набор номеров UTF-8: https://stackoverflow.com/a/14601808/1405208

Код, который я получил:

decodeUTF16LE(binaryStr) {
      if (binaryStr.charCodeAt(0) != 255 || binaryStr.charCodeAt(1) != 254) {
        return binaryStr;
      }
      const utf8 = [];
      for (var i = 2; i < binaryStr.length; i += 2) {
        let charcode = binaryStr.charCodeAt(i) | (binaryStr.charCodeAt(i + 1) << 8);
        if (charcode < 0x80) utf8.push(charcode);
        else if (charcode < 0x800) {
          utf8.push(0xc0 | (charcode >> 6), 0x80 | (charcode & 0x3f));
        } else if (charcode < 0xd800 || charcode >= 0xe000) {
          utf8.push(0xe0 | (charcode >> 12), 0x80 | ((charcode >> 6) & 0x3f), 0x80 | (charcode & 0x3f));
        }
        // surrogate pair
        else {
          i++;
          // UTF-16 encodes 0x10000-0x10FFFF by
          // subtracting 0x10000 and splitting the
          // 20 bits of 0x0-0xFFFFF into two halves
          charcode = 0x10000 + (((charcode & 0x3ff) << 10) | (charcode & 0x3ff));
          utf8.push(
            0xf0 | (charcode >> 18),
            0x80 | ((charcode >> 12) & 0x3f),
            0x80 | ((charcode >> 6) & 0x3f),
            0x80 | (charcode & 0x3f)
          );
        }
      }
      return String.fromCharCode.apply(String, utf8);
},

person NatanS    schedule 13.07.2021

person    schedule
comment
Что делать, если я не уверен, что мой файл будет закодирован в utf16? - person Julien Fouilhé; 18.11.2015
comment
Это то, что вам придется ограничить. Либо подтвердите, что это utf16, либо выясните тип. Обычно вы можете запрашивать входящие данные, чтобы найти тип и вставить указанный тип для ucs2. - person Ravenous; 18.11.2015