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?

30
demandé sur gsamaras 2014-09-12 17:58:33

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.

51
répondu Rob W 2014-09-12 17:33:48

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

1
répondu Edy Segura 2018-04-03 00:56:11