基于這個執行緒,我嘗試使用 utf 32 編碼和 FF FE 00 00(UTF-32LE 表示)的 BOM 創建一個 blob,如下所示:
var BOM = new Uint8Array([0xFF,0xFE,0x00,0x00]);
var b = new Blob([ BOM, "??? Test" ]);
var url = URL.createObjectURL(b);
open(url);
但是檔案內容已損壞并更改為其他語言。將字串轉換為 utf-32le 格式的檔案的正確方法是什么?
編輯:我在瀏覽器環境中嘗試這個
uj5u.com熱心網友回復:
注意:我假設您在瀏覽器中執行此操作,因為您使用 Blob 和 Node.js 最近才獲得 Blob 支持,并且您參考了在瀏覽器中執行此操作的問題。
您只是在設定 BOM,而不是在處理轉換資料。正如MDN 檔案中所說,陣列中的任何字串都將使用 UTF-8 進行編碼。所以你有一個 UTF-32LE BOM,后跟 UTF-8 資料。
令人驚訝的是(對我而言),瀏覽器平臺似乎沒有通用文本編碼器(TextEncoder僅編碼 UTF-8),但 JavaScript 字串提供了一種遍歷其代碼點(不僅僅是代碼單元)并獲取實際的 Unicode 代碼點值。(如果這些術語不熟悉,我的博客文章What is a string?可能會有所幫助。)因此您可以獲取該數字并將其轉換為四個 little-endian 位元組。DataView提供了一種方便的方法來做到這一點。
最后,您需要在 blob 的 MIME 型別中指定字符集(BOM 本身是不夠的)。我希望text/plain; charset=UTF-32LE作業,但它沒有,至少在 Chromium 瀏覽器中沒有。這可能有一些遺留的原因。text/html作業(單獨),但我們不妨具體并做text/html; charset=UTF-32LE.
看評論:
function getUTF32LEUrl(str) {
// The UTF-32LE BOM
const BOM = new Uint8Array([0xFF,0xFE,0x00,0x00]);
// A byte array and DataView to use when converting 32-bit LE to bytes;
// they share an underlying buffer
const uint8 = new Uint8Array(4);
const view = new DataView(uint8.buffer);
// Convert the payload to UTF-32LE
const utf32le = Array.from(str, (ch) => {
// Get the code point
const codePoint = ch.codePointAt(0);
// Write it as a 32-bit LE value in the buffer
view.setUint32(0, codePoint, true);
// Read it as individual bytes and create a plain array of them
return Array.from(uint8);
}).flat(); // Flatten the array of arrays into one long byte sequence
// Create the blob and URL
const b = new Blob(
[ BOM, new Uint8Array(utf32le)],
{ type: "text/html; charset=UTF-32LE"} // Set the MIME type
);
const url = URL.createObjectURL(b);
return url;
}
但請注意,該規范“禁止”瀏覽器支持HTML 的 UTF-32(LE 或 BE):
13.2.3.3 字符編碼
用戶代理必須支持編碼中定義的編碼,包括但不限于 UTF-8、ISO-8859-2、ISO-8859-7、ISO-8859-8、windows-874、windows-1250、windows-1251 , windows-1252, windows-1254, windows-1255, windows-1256, windows-1257, windows-1258, GBK, Big5, ISO-2022-JP, Shift_JIS, EUC-KR, UTF-16BE, UTF-16LE, UTF -16BE/LE 和 x 用戶定義。用戶代理不得支持其他編碼。
注意:以上禁止支持,例如 CESU-8、UTF-7、BOCU-1、SCSU、EBCDIC 和 UTF-32。本規范不嘗試在其演算法中支持禁止的編碼;因此,支持和使用禁止的編碼會導致意外行為。[CESU8] [UTF7] [BOCU1] [SCSU??]
鑒于您正在使用其中一種 UTF-16window.open來打開結果,您可能會更好。(對于下載,如果你真的想要一個 UTF-32 檔案,UTF-32 就可以了。)
遺憾的是,Stack Snippets 不會讓您打開新視窗,但這里有一個完整的示例,您可以復制并粘貼到本地運行:
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<title>UTF-32 Conversion</title>
<link rel="shortcut icon" href="favicon.png">
<style>
body, html {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
box-sizing: border-box;
}
*, *:before, *:after {
box-sizing: inherit;
}
</style>
</head>
<body>
<input type="button" value="Open" id="open">
<input type="button" value="Download" id="download">
<script type="module">
function getUTF32LEUrl(str, mimeType) {
// The UTF-32LE BOM
const BOM = new Uint8Array([0xFF,0xFE,0x00,0x00]);
// A byte array and DataView to use when converting 32-bit LE to bytes;
// they share an underlying buffer
const uint8 = new Uint8Array(4);
const view = new DataView(uint8.buffer);
// Convert the payload to UTF-32LE
const utf32le = Array.from(str, (ch) => {
// Get the code point
const codePoint = ch.codePointAt(0);
// Write it as a 32-bit LE value in the buffer
view.setUint32(0, codePoint, true);
// Read it as individual bytes and create a plain array of them
return Array.from(uint8);
}).flat(); // Flatten the array of arrays into one long byte sequence
// Create the blob and URL
const b = new Blob(
[ BOM, new Uint8Array(utf32le)],
mimeType // Set the MIME type
);
const url = URL.createObjectURL(b);
return url;
}
document.getElementById("open").addEventListener("click", () => {
const str = "??? Test";
const url = getUTF32LEUrl(str, { type: "text/html; charset=UTF-32LE" });
window.open(url);
});
document.getElementById("download").addEventListener("click", () => {
const str = "??? Test";
const url = getUTF32LEUrl(str, { type: "text/plain; charset=UTF-32LE" });
const a = document.createElement("a");
a.download = "utf-32_file.txt";
a.href = url;
a.click();
document.body.removeChild(a);
});
</script>
</body>
</html>
uj5u.com熱心網友回復:
我嘗試過這樣的事情......
var fs = require('fs');
var iconv = require('iconv-lite');
var str = '你好,世界';
var buf = iconv.encode(str, 'utf-32le');
fs.writeFileSync('test.txt', buf);
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/531518.html
上一篇:如何將csv轉換為json
