我使用FileReader.readAsArrayBuffer
遇到一个奇怪的问题,这似乎只会影响Firefox(我在当前版本中测试过 - v40)。我不知道我是做错了还是这是一个Firefox错误。
我有一些JavaScript使用readAsArrayBuffer
来读取<input>
字段中指定的文件。在正常情况下,一切正常。但是,如果用户在<input>
字段中选择文件后修改了该文件,则readAsArrayBuffer
可能会非常混乱。
我从ArrayBuffer
返回的readAsArrayBuffer
始终具有文件最初的长度。如果用户更改文件以使其更大,我不会获得原始大小后的任何字节。如果用户更改文件使其变小,则缓冲区仍然是相同的大小,缓冲区中的“多余”用字符代码90填充(大写字母'Z',如果被视为字符串)。
由于此代码非常简单,并且在我测试的其他所有浏览器中都能完美运行,因此我认为这是一个Firefox问题。我已经reported it as a bug访问了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/
答案 0 :(得分:11)
有趣的是,即使文件被修改,Firefox也会缓存缓冲区大小。
您可以参考此link,将expr : expr2 (assignment_operator expr3)? # Equals
expr2 : expr1 (binary_op expr2)? # Add
expr1 : Identifier |
expr1 . Identifier
;
替换为使用readAsArrayBuffer
的自定义功能。它在Firefox和Chrome中运行良好
readAsBinaryString
答案 1 :(得分:6)
我认为你正在遇到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
。