w3schools readasdataurl read javascript firefox filereader fileapi

readasdataurl - read file javascript



Uso de FileReader.readAsArrayBuffer() en archivos modificados en Firefox (2)

Creo que estás golpeando un error de Firefox. Sin embargo, como señaló, readAsArrayBuffer comporta correctamente en todos los navegadores compatibles, excepto en Firefox, mientras que readAsBinaryString es compatible con todos los navegadores, excepto IE.

Por lo tanto, es posible preferir readAsBinaryString cuando exista y, en readAsArrayBuffer contrario, volver a 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); } }

Uso:

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); });

Fiddle de trabajo: https://jsfiddle.net/Lv5y9m2u/6/

Soporte del navegador:

  • Firefox: utiliza readAsBinaryString , que no es problemático.
  • IE> = 10: utiliza readAsArrayBuffer que es compatible.
  • IE <= 9: no se admite la API completa de FileReader .
  • Casi todos los demás navegadores: utiliza readAsBinaryString .

Estoy encontrando un problema extraño con FileReader.readAsArrayBuffer que solo parece afectar a Firefox (lo probé en la versión actual - v40). No puedo decir si estoy haciendo algo mal o si se trata de un error de Firefox.

Tengo algo de JavaScript que usa readAsArrayBuffer para leer un archivo especificado en un campo <input> . En circunstancias normales, todo funciona correctamente. Sin embargo, si el usuario modifica el archivo después de seleccionarlo en el campo <input> , readAsArrayBuffer puede confundirse.

El ArrayBuffer que recibo de readAsArrayBuffer siempre tiene la longitud original del archivo. Si el usuario cambia el archivo para hacerlo más grande, no obtengo ninguno de los bytes después del tamaño original. Si el usuario cambia el archivo para hacerlo más pequeño, el búfer sigue siendo del mismo tamaño y el "exceso" en el búfer está lleno de códigos de caracteres 90 (mayúscula "Z" si se ve como una cadena).

Dado que este código es muy simple y funciona perfectamente en todos los demás navegadores que probé, creo que es un problema de Firefox. Lo he reportado como un error a Firefox, pero quiero asegurarme de que esto no es algo obvio que estoy haciendo mal.

El comportamiento puede ser reproducido por el siguiente fragmento de código. Todo lo que tienes que hacer es:

  1. Busque un archivo de texto que tenga 10 caracteres (10 no es un número mágico, solo lo estoy usando como ejemplo)
  2. Observe que el resultado es una matriz de 10 elementos que representan los códigos de caracteres de cada elemento.
  3. Mientras esto se está ejecutando, elimine 5 caracteres del archivo y guarde
  4. Observe que el resultado sigue siendo un conjunto de 10 elementos: los primeros 5 son correctos pero los últimos 5 son todos 90 (mayúscula Z)
  5. Ahora se agregan 10 caracteres (por lo tanto, el archivo ahora tiene 15 caracteres de longitud)
  6. Observe que el resultado sigue siendo una matriz de 10 elementos; los últimos 5 no se devuelven

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>

En caso de que el fragmento no funcione, el código de ejemplo también está disponible como JSFiddle aquí: https://jsfiddle.net/Lv5y9m2u/


Interesante, parece que Firefox está almacenando en caché el tamaño del búfer, incluso el archivo está modificado.

Puede consultar este link , reemplazado por readAsArrayBuffer con una funcionalidad personalizada que utiliza readAsBinaryString . Está funcionando bien en Firefox y 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();