在Firefox中使用FileReader.readAsArrayBuffer()更改文件 [英] Using FileReader.readAsArrayBuffer() on changed files in Firefox
问题描述
我使用 FileReader遇到了一个奇怪的问题。 readAsArrayBuffer
,似乎只影响Firefox(我在当前版本 - v40测试)。我不知道是否我只是做错了什么,或者这是一个Firefox错误。
我有一些使用 readAsArrayBuffer
来读取< input>
字段中指定的文件。一般情况下,一切正常。但是,如果用户在< input>
字段中选择了该文件,那么 readAsArrayBuffer
会变得非常困惑。
$ b $
ArrayBuffer
我从 readAsArrayBuffer
返回有文件的长度。如果用户更改文件以使其更大,则不会获得原始大小之后的任何字节。如果用户改变文件使其变小,那么缓冲区仍然是相同的大小,而缓冲区中的多余则用字符代码90填充(大写字母Z,如果被视为一个字符串)。 b $ b
由于这段代码非常简单,在我测试的其他所有浏览器中都能很好地工作,所以我认为这是一个Firefox问题。我已经向Firefox报告这是一个错误,但我想确保这不仅仅是显然我做错了。
行为可以通过下面的代码片段来重现。所有你需要做的是:
- 浏览一个有10个字符的文本文件(10不是幻数 - 以这个为例)
- 观察结果是一个由10个项目组成的数组,代表每个项目的字符代码
- 仍然运行,从文件中删除5个字符并保存
- 观察结果仍然是一个10个数组的数组 - 前5个是正确的,但是最后5个都是90(大写字母Z )
- 现在添加了10个字符(因此文件现在是15个字符)
- 观察结果仍然是一个10个数组的数组 - 最后5个不会返回
< input type =file/>< br />< textarea cols =80rows =10>< / textarea>
https://jsfiddle.net/Lv5y9m2u/解决方案有趣的是,看起来像FF正在缓存缓冲区大小,甚至文件被修改。
你可以参考这个链接,替换readAsArrayBuffer是使用readAsBinaryString的自定义功能。它在FF和铬工作正常
function ReadFile(){
var input = document.getElementsByTagName(input )[0];
var output = document.getElementsByTagName(textarea)[0];
if(input.files.length === 0){
output.value ='没有选择文件';
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]);
//这两个方法正常工作
//fr.readAsText (input.files[0]);
//fr.readAsBinaryString (input.files[0]);
if(FileReader.prototype.readAsArrayBuffer& FileReader.prototype.readAsBinaryString){
FileReader.prototype.readAsArrayBuffer = function readAsArrayBuffer(){
this.readAsBinaryString。应用(this,arguments);
this .__ defineGetter __('resultString',this .__ lookupGetter __('result'));
this .__ defineGetter __('result',function(){
var string = this.resultString;
var result = new Uint8Array(string.length); $ b $ for(var i = 0; i< string.length; i ++){
result [i] = string.charCodeAt(i);
}
return result.buffer;
});
};
}
ReadFile();
I'm running into an odd problem using
FileReader.readAsArrayBuffer
that only seems to affect Firefox (I tested in the current version - v40). I can't tell if I'm just doing something wrong or if this is a Firefox bug.I have some JavaScript that uses
readAsArrayBuffer
to read a file specified in an<input>
field. Under normal circumstances, everything works correctly. However, if the user modifies the file after selecting it in the<input>
field,readAsArrayBuffer
can get very confused.The
ArrayBuffer
I get back fromreadAsArrayBuffer
always has the length that the file was originally. If the user changes the file to make it larger, I don't get any of the bytes after the original size. If the user changes the file to make it smaller, the buffer is still the same size and the 'excess' in the buffer is filled with character codes 90 (capital letter 'Z' if viewed as a string).Since this code is so simple and works perfectly in every other browser I tested, I'm thinking it's a Firefox issue. I've reported it as a bug to Firefox but I want to make sure this isn't just something obvious I'm doing wrong.
The behavior can be reproduced by the following code snippet. All you have to do is:
- Browse for a text file that has 10 characters in it (10 is not a magic number - I'm just using it as an example)
- Observe that the result is an array of 10 items representing the character codes of each item
- While this is still running, delete 5 characters from the file and save
- Observe that the result is still an array of 10 items - the first 5 are correct but the last 5 are all 90 (capital letter Z)
- Now added 10 characters (so the file is now 15 characters long)
- Observe that the result is still an array of 10 items - the last 5 are not returned
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>
In case the snippet does not work, the sample code is also available as a JSFiddle here: https://jsfiddle.net/Lv5y9m2u/
解决方案Interesting, looks like FF 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 FF 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();
这篇关于在Firefox中使用FileReader.readAsArrayBuffer()更改文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!