[英]loading image using javascript FileReader.readAsArrayBuffer
[英]Using FileReader.readAsArrayBuffer() on changed files in Firefox
我正在使用FileReader.readAsArrayBuffer
遇到一个奇怪的问题,它似乎只影响Firefox(我在当前版本中测试过 - v40)。 我不知道我是做错了还是这是一个Firefox bug。
我有一些JavaScript使用readAsArrayBuffer
来读取<input>
字段中指定的文件。 在正常情况下,一切正常。 但是,如果用户在<input>
字段中选择文件后修改文件, readAsArrayBuffer
可能会变得非常困惑。
我从readAsArrayBuffer
返回的ArrayBuffer
总是具有文件最初的长度。 如果用户更改文件以使其更大,我不会获得原始大小后的任何字节。 如果用户更改文件以使其变小,则缓冲区仍然具有相同的大小,并且缓冲区中的“多余”填充有字符代码90(如果被视为字符串则为大写字母'Z')。
由于此代码非常简单,并且在我测试的其他所有浏览器中都能完美运行,因此我认为这是一个Firefox问题。 我已经将它报告为 Firefox的一个错误 ,但我想确保这不仅仅是我做错了。
可以通过以下代码段重现该行为。 你所要做的就是:
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]); } ReadFile();
<input type="file" /> <br/> <textarea cols="80" rows="10"></textarea>
如果代码片段不起作用,示例代码也可以在这里作为JSFiddle: https ://jsfiddle.net/Lv5y9m2u/
有趣的是,看起来Firefox即使文件被修改也会缓存缓冲区大小。
您可以参考此链接 ,将readAsArrayBuffer
替换为使用readAsBinaryString
自定义功能。 它在Firefox和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();
我认为你正在遇到Firefox的错误。 但是,正如您所指出的, readAsArrayBuffer
在除Firefox之外的每个支持的浏览器中都能正常运行,而除了IE之外的每个浏览器都支持readAsBinaryString
。
因此,当它存在时,可能更喜欢readAsBinaryString
,否则返回readAsArrayBuffer
。
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);
}
}
用法:
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);
});
工作小提琴: https : //jsfiddle.net/Lv5y9m2u/6/
浏览器支持:
readAsBinaryString
,这没有问题。 readAsArrayBuffer
。 FileReader
API。 readAsBinaryString
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.