在Firefox中使用FileReader.readAsArrayBuffer()更改文件 [英] Using FileReader.readAsArrayBuffer() on changed files in Firefox

查看:1413
本文介绍了在Firefox中使用FileReader.readAsArrayBuffer()更改文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 FileReader遇到了一个奇怪的问题。 readAsArrayBuffer ,似乎只影响Firefox(我在当前版本 - v40测试)。我不知道是否我只是做错了什么,或者这是一个Firefox错误。

我有一些使用 readAsArrayBuffer 来读取< input> 字段中指定的文件。一般情况下,一切正常。但是,如果用户在< input> 字段中选择了该文件,那么 readAsArrayBuffer 会变得非常困惑。


$ b $ ArrayBuffer 我从 readAsArrayBuffer 返回有文件的长度。如果用户更改文件以使其更大,则不会获得原始大小之后的任何字节。如果用户改变文件使其变小,那么缓冲区仍然是相同的大小,而缓冲区中的多余则用字符代码90填充(大写字母Z,如果被视为一个字符串)。 b
$ b

由于这段代码非常简单,在我测试的其他所有浏览器中都能很好地工作,所以我认为这是一个Firefox问题。我已经向Firefox报告这是一个错误,但我想确保这不仅仅是显然我做错了。

行为可以通过下面的代码片段来重现。所有你需要做的是:


  1. 浏览一个有10个字符的文本文件(10不是幻数 - 以这个为例)

  2. 观察结果是一个由10个项目组成的数组,代表每个项目的字符代码
  3. 仍然运行,从文件中删除5个字符并保存
  4. 观察结果仍然是一个10个数组的数组 - 前5个是正确的,但是最后5个都是90(大写字母Z )

  5. 现在添加了10个字符(因此文件现在是15个字符)

  6. 观察结果仍然是一个10个数组的数组 - 最后5个不会返回

[0]; var output = document.getElementsByTagName(textarea)[0]; if(input.files.length === 0){output.value ='没有选择文件'; window.setTimeout(ReadFile,1000);返回; } 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]);}ReadFile();

 < 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 from readAsArrayBuffer 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:

  1. 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)
  2. Observe that the result is an array of 10 items representing the character codes of each item
  3. While this is still running, delete 5 characters from the file and save
  4. 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)
  5. Now added 10 characters (so the file is now 15 characters long)
  6. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆