filereader api en files grandes

Mi código api de lector de files ha funcionado bien hasta el momento en que un día recibí un file txt de 280MB de uno de mis clientes. La página simplemente se bloquea directamente en Chrome y en Firefox no pasa nada.

// create new reader object var fileReader = new FileReader(); // read the file as text fileReader.readAsText( $files[i] ); fileReader.onload = function(e) { // read all the information about the file // do sanity checks here etc... $timeout( function() { // var fileContent = e.target.result; // get the first line var firstLine = e.target.result.slice(0, e.target.result.indexOf("\n") ); }} 

Lo que bash hacer arriba es get el primer salto de línea para poder get la longitud de la columna del file. ¿No debería leerlo como text? ¿Cómo puedo get la longitud de columna del file sin romper la página en files grandes?

Su aplicación está fallando para files grandes porque está leyendo todo el file en la memory antes de procesarlo. Esta ineficiencia puede resolverse mediante la transmisión del file (lectura de fragments de un tamaño pequeño), por lo que solo necesita mantener una parte del file en la memory.

Un object File también es una instancia de un Blob , que ofrece el método .slice para crear una vista más pequeña del file.

Aquí hay un ejemplo que supone que la input es ASCII (demo: http://jsfiddle.net/mw99v8d4/ ).

 function findColumnLength(file, callback) { // 1 KB at a time, because we expect that the column will probably small. var CHUNK_SIZE = 1024; var offset = 0; var fr = new FileReader(); fr.onload = function() { var view = new Uint8Array(fr.result); for (var i = 0; i < view.length; ++i) { if (view[i] === 10 || view[i] === 13) { // \n = 10 and \r = 13 // column length = offset + position of \r or \n callback(offset + i); return; } } // \r or \n not found, continue seeking. offset += CHUNK_SIZE; seek(); }; fr.onerror = function() { // Cannot read file... Do something, eg assume column size = 0. callback(0); }; seek(); function seek() { if (offset >= file.size) { // No \r or \n found. The column size is equal to the full // file size callback(file.size); return; } var slice = file.slice(offset, offset + CHUNK_SIZE); fr.readAsArrayBuffer(slice); } } 

El fragment anterior count el número de bytes antes de un salto de línea. Contar el número de caracteres en un text que consiste en caracteres multibyte es un poco más difícil, porque debe tener en count la posibilidad de que el último byte en el fragment pueda formar parte de un carácter multibyte.