Using FileReader.readAsArrayBuffer() on changed files in Firefox

六眼飞鱼酱① 提交于 2019-12-03 02:49:48
Pavan Kumar Jorrigala

Interesting, looks like Firefox is caching the buffer size even the file is modified.

You can refer to this link, replaced readAsArrayBuffer with is custom functionality which uses readAsBinaryString. Its working fine in Firefox and Chrome

function ReadFile() {
var input = document.getElementsByTagName("input")[0];
var output = document.getElementsByTagName("textarea")[0];

if (input.files.length === 0) {
    output.value = 'No file selected';
    window.setTimeout(ReadFile, 1000);
    return;
}

var fr = new FileReader();
fr.onload = function () {
    var data = fr.result;
    var array = new Int8Array(data);
    output.value = JSON.stringify(array, null, '  ');
    window.setTimeout(ReadFile, 1000);
};
fr.readAsArrayBuffer(input.files[0]);



//These two methods work correctly
//fr.readAsText(input.files[0]);
//fr.readAsBinaryString(input.files[0]);
}
if (FileReader.prototype.readAsArrayBuffer && FileReader.prototype.readAsBinaryString) {
    FileReader.prototype.readAsArrayBuffer = function readAsArrayBuffer () {
        this.readAsBinaryString.apply(this, arguments);
        this.__defineGetter__('resultString', this.__lookupGetter__('result'));
        this.__defineGetter__('result', function () {
            var string = this.resultString;
            var result = new Uint8Array(string.length);
            for (var i = 0; i < string.length; i++) {
                result[i] = string.charCodeAt(i);
            }
            return result.buffer;
        });
    };
}
ReadFile();

I think you are hitting a bug of Firefox. However, as you pointed out, readAsArrayBuffer behaves correctly in every supported browser except Firefox while readAsBinaryString is supported by every browser except IE.

Therefore, it is possible to prefer readAsBinaryString when it exists and fail back to readAsArrayBuffer otherwise.

function readFileAsArrayBuffer(file, success, error) {
    var fr = new FileReader();
    fr.addEventListener('error', error, false);
    if (fr.readAsBinaryString) {
        fr.addEventListener('load', function () {
            var string = this.resultString != null ? this.resultString : this.result;
            var result = new Uint8Array(string.length);
            for (var i = 0; i < string.length; i++) {
                result[i] = string.charCodeAt(i);
            }
            success(result.buffer);
        }, false);
        return fr.readAsBinaryString(file);
    } else {
        fr.addEventListener('load', function () {
            success(this.result);
        }, false);
        return fr.readAsArrayBuffer(file);
    }
}

Usage:

readFileAsArrayBuffer(input.files[0], function(data) {
    var array = new Int8Array(data);
    output.value = JSON.stringify(array, null, '  ');
    window.setTimeout(ReadFile, 1000);
}, function (e) {
    console.error(e);
});

Working fiddle: https://jsfiddle.net/Lv5y9m2u/6/

Browser Support:

  • Firefox: Uses readAsBinaryString, which is not problematic.
  • IE >= 10: Uses readAsArrayBuffer which is supported.
  • IE <= 9: The entire FileReader API is not supported.
  • Almost all other browsers: Uses readAsBinaryString.
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!