javascript - manejo - filereader api en archivos grandes
read file javascript (2)
¡Hay una increíble biblioteca llamada Papa Parse que hace eso de una manera elegante! Realmente puede manejar archivos grandes y también puede usar web worker.
Solo prueba las demos que proporcionan: https://www.papaparse.com/demo
Mi código api de lector de archivos ha funcionado bien hasta el momento en que un día recibí un archivo 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 intento hacer arriba es obtener el primer salto de línea para poder obtener la longitud de la columna del archivo. ¿No debería leerlo como texto? ¿Cómo puedo obtener la longitud de columna del archivo sin romper la página en archivos grandes?
Su aplicación está fallando para archivos grandes porque está leyendo todo el archivo en la memoria antes de procesarlo. Esta ineficiencia puede resolverse mediante la transmisión del archivo (lectura de fragmentos de un tamaño pequeño), por lo que solo necesita mantener una parte del archivo en la memoria.
Un objeto File
también es una instancia de un Blob
, que ofrece el método .slice
para crear una vista más pequeña del archivo.
Aquí hay un ejemplo que supone que la entrada 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, e.g. 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 fragmento anterior cuenta el número de bytes antes de un salto de línea. Contar el número de caracteres en un texto que consiste en caracteres multibyte es un poco más difícil, porque debe tener en cuenta la posibilidad de que el último byte en el fragmento pueda formar parte de un carácter multibyte.