Примечание в 2018 : readAsBinaryString
устарело.В тех случаях, когда ранее вы использовали его, в наши дни вместо этого вы будете использовать readAsArrayBuffer
(или в некоторых случаях readAsDataURL
).
readAsBinaryString
говорит, что данные должны быть представлены в виде двоичной строки , где:
... каждый байт представленцелое число в диапазоне [0..255].
Изначально JavaScript не имел «двоичного» типа (до тех пор, пока ECMAScript 5 не поддерживал WebGL Typed Array * (подробности ниже) - он был заменен на ECMAScript 2015 ArrayBuffer ), поэтому они использовали строку, гарантирующую, что ни один символ, хранящийся в строке, не будет вне диапазона 0 ..255.(Вместо этого они могли бы использовать массив чисел, но это не так; возможно, большие строки более эффективны по памяти, чем большие массивы чисел, поскольку числа с плавающей запятой.)
Если выпри чтении файла, который в основном представляет собой текст в западном сценарии (например, в основном на английском языке), эта строка будет выглядеть как текст lot .Если вы читаете файл с символами Юникода в нем, вы должны заметить разницу, поскольку строки JavaScript: UTF-16 ** (подробности ниже) , и поэтому некоторые символы будут иметь значения выше255, тогда как «двоичная строка» в соответствии со спецификацией File API не будет иметь значений выше 255 (у вас будет два отдельных «символа» для двух байтов кодовой точки Unicode).
Есливы читаете файл, который вообще не является текстом (возможно, изображение), вы, вероятно, все равно получите очень похожий результат между readAsText
и readAsBinaryString
, но с readAsBinaryString
вы знаете что не будет никаких попыток интерпретировать многобайтовые последовательности как символы.Вы не знаете, что если вы используете readAsText
, потому что readAsText
будет использовать определение кодировки , чтобы попытаться выяснить, какова кодировка файла, а затем сопоставить его со строками JavaScript UTF-16.
Вы можете увидеть эффект, если создадите файл и сохраните его в чем-то отличном от ASCII или UTF-8.(В Windows вы можете сделать это через Блокнот; раскрывающийся список «Сохранить как» в виде кодировки с надписью «Юникод», в котором при просмотре данных они означают UTF-16; я уверен, что Mac OS и *Редакторы nix имеют похожую функцию.) Вот страница, которая выводит результат чтения файла обоими способами:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
<title>Show File Data</title>
<style type='text/css'>
body {
font-family: sans-serif;
}
</style>
<script type='text/javascript'>
function loadFile() {
var input, file, fr;
if (typeof window.FileReader !== 'function') {
bodyAppend("p", "The file API isn't supported on this browser yet.");
return;
}
input = document.getElementById('fileinput');
if (!input) {
bodyAppend("p", "Um, couldn't find the fileinput element.");
}
else if (!input.files) {
bodyAppend("p", "This browser doesn't seem to support the `files` property of file inputs.");
}
else if (!input.files[0]) {
bodyAppend("p", "Please select a file before clicking 'Load'");
}
else {
file = input.files[0];
fr = new FileReader();
fr.onload = receivedText;
fr.readAsText(file);
}
function receivedText() {
showResult(fr, "Text");
fr = new FileReader();
fr.onload = receivedBinary;
fr.readAsBinaryString(file);
}
function receivedBinary() {
showResult(fr, "Binary");
}
}
function showResult(fr, label) {
var markup, result, n, aByte, byteStr;
markup = [];
result = fr.result;
for (n = 0; n < result.length; ++n) {
aByte = result.charCodeAt(n);
byteStr = aByte.toString(16);
if (byteStr.length < 2) {
byteStr = "0" + byteStr;
}
markup.push(byteStr);
}
bodyAppend("p", label + " (" + result.length + "):");
bodyAppend("pre", markup.join(" "));
}
function bodyAppend(tagName, innerHTML) {
var elm;
elm = document.createElement(tagName);
elm.innerHTML = innerHTML;
document.body.appendChild(elm);
}
</script>
</head>
<body>
<form action='#' onsubmit="return false;">
<input type='file' id='fileinput'>
<input type='button' id='btnLoad' value='Load' onclick='loadFile();'>
</form>
</body>
</html>
Если я использую это с файлом «Testing 1 2 3», хранящимся в UTF-16,Вот результаты, которые я получаю:
Text (13):
54 65 73 74 69 6e 67 20 31 20 32 20 33
Binary (28):
ff fe 54 00 65 00 73 00 74 00 69 00 6e 00 67 00 20 00 31 00 20 00 32 00 20 00 33 00
Как видите, readAsText
интерпретировал символы, и поэтому я получил 13 (длина «Тестирование 1 2 3») и readAsBinaryString
didn 'т, и поэтому я получил 28 (двухбайтовая BOM плюс два байта для каждого символа).
* XMLHttpRequest.response с responseType = "arraybuffer"
поддерживается в HTML 5.
** "Строки JavaScript имеют UTF-16" может показаться странным утверждением;они не просто Unicode?Нет, строка JavaScript - это серия кодовых единиц UTF-16 ;Вы видите суррогатные пары как два отдельных «символа» JavaScript, хотя на самом деле суррогатная пара в целом - это всего лишь один символ.Подробнее смотрите по ссылке.