Je rencontre un problème étrange en utilisant FileReader.readAsArrayBuffer
qui ne semble affecter que Firefox (j'ai testé dans la version actuelle - v40). Je ne peux pas dire si je fais juste quelque chose de mal ou s'il s'agit d'un bogue Firefox.
J'ai du JavaScript qui utilise readAsArrayBuffer
pour lire un fichier spécifié dans un <input>
champ. Dans des circonstances normales, tout fonctionne correctement. Cependant, si l'utilisateur modifie le fichier après l'avoir sélectionné dans le <input>
champ, readAsArrayBuffer
peut devenir très confus.
ArrayBuffer
je reviens de readAsArrayBuffer
a toujours la longueur d'origine du fichier. Si l'utilisateur modifie le fichier pour l'agrandir, je n'obtiens aucun des octets après la taille d'origine. Si l'utilisateur modifie le fichier pour le rendre plus petit, le tampon est toujours de la même taille et le "surplus" dans le tampon est rempli avec les codes de caractères 90 (lettre majuscule "Z" si vue comme une chaîne).
Étant donné que ce code est si simple et fonctionne parfaitement dans tous les autres navigateurs que j'ai testés, je pense que c'est un problème avec Firefox. J'ai signalé comme bogue à Firefox mais je veux m'assurer que ce n'est pas seulement quelque chose d'évident que je fais mal.
Le comportement peut être reproduit par l'extrait de code suivant. Tout ce que tu dois faire est:
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>
Dans le cas où l'extrait ne fonctionne pas, l'exemple de code est également disponible en tant que JSFiddle ici: https://jsfiddle.net/Lv5y9m2u/
Intéressant, on dirait que Firefox met en cache la taille du tampon même si le fichier est modifié.
Vous pouvez vous y référer link , remplacé readAsArrayBuffer
avec sa fonctionnalité personnalisée qui utilise readAsBinaryString
. Son fonctionne bien dans Firefox et 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();
Je pense que vous rencontrez un bug de Firefox. Cependant, comme vous l'avez souligné, readAsArrayBuffer
se comporte correctement dans tous les navigateurs pris en charge, à l'exception de Firefox, tandis que readAsBinaryString
est pris en charge par tous les navigateurs, sauf IE.
Par conséquent, il est possible de préférer readAsBinaryString
lorsqu'il existe et de revenir à readAsArrayBuffer
sinon.
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);
});
Violon de travail: https://jsfiddle.net/Lv5y9m2u/6/
Prise en charge du navigateur:
readAsBinaryString
, ce qui n'est pas problématique.readAsArrayBuffer
qui est pris en charge.FileReader
n'est pas prise en charge.readAsBinaryString
.