代码之家  ›  专栏  ›  技术社区  ›  tcooc

HTML5文件API以文本和二进制形式读取

  •  31
  • tcooc  · 技术社区  · 15 年前

    我目前正在工作的HTML5文件API,我需要得到二进制文件数据。 The FileReader readAsText readAsDataURL 方法很管用,但是 readAsBinaryString 返回与相同的数据 .

    我需要二进制数据,但我得到一个文本字符串。我错过什么了吗?

    1 回复  |  直到 4 年前
        1
  •  76
  •   T.J. Crowder    6 年前

    2018年附注 : readAsBinaryString 已经过时了。对于以前使用过的用例,现在使用 readAsArrayBuffer (或在某些情况下, readAsDataURL )相反。


    表示数据必须表示为 binary string ,其中:

    Typed Array (详情如下) ArrayBuffer )所以他们使用了一个字符串,保证字符串中存储的字符不会超出0..255的范围(他们本可以用一组数字代替,但他们没有;也许大字符串比大的数字数组更节省内存,因为数字是浮点型的。)

    如果您正在读取的文件大部分是西文脚本中的文本(例如,大部分是英文),那么该字符串将看起来像一个 许多 UTF-16 (详情如下) 因此,有些字符的值会超过255,而根据文件API规范,“二进制字符串”的值不会超过255(Unicode代码点的两个字节有两个单独的“字符”)。

    如果您正在读取一个完全不是文本的文件(可能是一个图像),您可能仍然会得到一个非常相似的结果 readAsText readAsBinaryString文件 readAsBinaryString文件 不会有人试图将多字节序列解释为字符。如果你使用 阅读文本 ,因为 将使用 encoding determination 尝试找出文件的编码,然后将其映射到JavaScript的UTF-16字符串。

    如果您创建一个文件并将其存储在ASCII或UTF-8以外的其他格式中,则可以看到效果;“另存为”是一个编码下拉列表,上面有“Unicode”,通过这个下拉列表查看数据,它们似乎是指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>
    

    如果我将其与存储在UTF-16中的“Testing 1 2 3”文件一起使用,我将得到以下结果:

    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

    阅读文本 readAsBinaryString文件 没有,所以我得到了28(两个字节) BOM 每个字符加两个字节)。


    XMLHttpRequest.response 具有 responseType = "arraybuffer"

    ** “JavaScript字符串是UTF-16” 似乎是一种奇怪的说法;它们不就是Unicode吗?不,JavaScript字符串是 a series of UTF-16 code units ; 您将代理项对视为两个单独的JavaScript“字符”,尽管实际上,代理项对作为一个整体只是一个字符。有关详细信息,请参见链接。