【问题标题】:Javascript: create UTF-16 text file?Javascript:创建 UTF-16 文本文件?
【发布时间】:2016-01-01 10:19:17
【问题描述】:

我有一些字符串需要是 UTF-16 文本文件。例如:

var s = "aosjdfkzlzkdoaslckjznx";
var file = "data:text/plain;base64," + btoa(s);

这将产生一个 UTF-8 编码的文本文件。如何获取带有字符串 s 的 UTF-16 文本文件?

【问题讨论】:

  • 您的文件是否需要位于data: URL 中?因为你可以用 Blob 轻松地做你想做的事。
  • 是的,我需要 base64。但我不喜欢 fileReaderAPI 因为它是异步的。它会使我的应用程序过于复杂。你有更好的建议吗?
  • 我建议您重新评估您的标准。 Web 应用程序使用异步的东西,这是不可避免的。但碰巧的是,使用 TextEncoder 和创建 Blob URI 不会是异步的。您不需要 File API,因为您不是在读取文件,而是在创建一个文件。
  • 我使用arrayBuffer直接转换为base64:stackoverflow.com/questions/9267899/…

标签: javascript utf-16


【解决方案1】:

相关:Javascript to csv export encoding issue

应该这样做:

document.getElementById('download').addEventListener('click', function(){

	downloadUtf16('Hello, World', 'myFile.csv')
});

function downloadUtf16(str, filename) {

	// ref: https://stackoverflow.com/q/6226189
	var charCode, byteArray = [];

	// BE BOM
  byteArray.push(254, 255);

	// LE BOM
  // byteArray.push(255, 254);

  for (var i = 0; i < str.length; ++i) {
  
    charCode = str.charCodeAt(i);
    
    // BE Bytes
    byteArray.push((charCode & 0xFF00) >>> 8);
    byteArray.push(charCode & 0xFF);
    
    // LE Bytes
    // byteArray.push(charCode & 0xff);
    // byteArray.push(charCode / 256 >>> 0);
  }
  
  var blob = new Blob([new Uint8Array(byteArray)], {type:'text/plain;charset=UTF-16BE;'});
  var blobUrl = URL.createObjectURL(blob);
  
	// ref: https://stackoverflow.com/a/18197511
  var link = document.createElement('a');
  link.href = blobUrl;
  link.download = filename;

  if (document.createEvent) {
    var event = document.createEvent('MouseEvents');
    event.initEvent('click', true, true);
    link.dispatchEvent(event);
  } else {
    link.click();
  }
}
&lt;button id="download"&gt;Download&lt;/button&gt;

【讨论】:

  • 对我有用!但是,在您的示例中,您正在使用 BE BOM,但是使用字符集 UTF-16LE 对您的 blob 进行编码。那不应该是UTF-16BE吗?
  • 你救了我的命。
  • 这是否也适用于 Unicode 代理对(参见 charCodeAtcodePointAt 文档),即 unicode 值大于 0xFFFF 的字符/表情符号?
【解决方案2】:

您可以使用原生 TextEncoder API 的旧版 polyfill 将 JavaScript 字符串转换为 ArrayBuffer。正如您将在该文档中看到的那样,支持具有 is 字节序的 UTF16。以与文本编码器兼容的方式提供 UTF-16 支持的库可能很快就会出现,如果它们还没有出现的话。假设有一个这样的库公开了一个名为 ExtendedTextEncoder 的构造函数。

然后您可以轻松创建 Blob URL 以允许用户下载文件,而无需进行低效的 base-64 转换。

类似这样的:

s = "aosjdfkzlzkdoaslckjznx"
var encoder = new ExtendedTextEncoder("utf-16be")
var blob = new Blob(encoder.encode(s), "text/plain")
var url = URL.createObjectURL(blob)

现在您可以使用url 代替您的data: URL。

【讨论】:

  • 请注意,UTF-16LE 文本文件有一个神奇的标题(FF、FE 或 255,254)。见:en.wikipedia.org/wiki/…
  • 很抱歉,我发现这在 Safari 中不起作用。 Safari 只是不支持 TextEncoder() 。 Safari还有其他解决方案吗?
  • 您可以为 TextEncoder 使用 polyfill。我可以推荐我链接的那个,我自己用过。它将创建一个 TextEncoder 对象,其行为与本机对象一样(仅当它不可用时)。
  • 哦,这是我第一次听说 polyfill。谢谢,它有效!
  • TextEncoder 不再接受编码字符串作为参数:developer.mozilla.org/en-US/docs/Web/API/TextEncoder/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-14
  • 2017-02-12
相关资源
最近更新 更多