api filereader sur les gros fichiers
Mon code api de lecteur de fichiers a bien fonctionné jusqu'à présent jusqu'au jour où j'ai reçu un fichier TXT de 280MB d'un de mes clients. La Page se bloque tout droit dans Chrome et dans Firefox rien ne se passe.
// 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") ); }}
Ce que j'essaie de faire ci-dessus est d'obtenir le premier saut de ligne afin que je puisse obtenir la longueur de la colonne du fichier. Ne devrais-je pas le lire comme texte ? Comment puis-je obtenir la longueur de la colonne du fichier sans casser la page sur les gros fichiers?
2 réponses
Votre application échoue pour les gros fichiers car vous lisez le fichier complet en mémoire avant de le traiter. Cette inefficacité peut être résolue en diffusant le fichier (en lisant des morceaux de petite taille), il vous suffit donc de conserver une partie du fichier en mémoire.
Un File
objects est également une instance d'un Blob
, qui offre la méthode .slice
pour créer une vue plus petite du fichier.
Voici un exemple qui suppose que l'entrée est 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);
}
}
L'extrait précédent compte le nombre d'octets avant un saut de ligne. Compter le nombre de caractères dans un texte composé de caractères multioctets est un peu plus difficile, car vous devez tenir compte de la possibilité que le dernier octet du bloc puisse faire partie d'un caractère multioctet.
Il y a une bibliothèque impressionnante appelée Papa Parse qui le fait d'une manière gracieuse! Il peut vraiment gérer de gros fichiers et vous pouvez également utiliser Web worker.
Juste essayer les démos qu'ils fournissent: https://www.papaparse.com/demo