64 votes

Obtenir les 10 dernières lignes d'un très gros fichier texte> 10 Go c #

Quel est le moyen le plus efficace d'afficher les 10 dernières lignes d'un fichier texte très volumineux (ce fichier en particulier dépasse 10 Go). Je pensais juste écrire une application simple c # mais je ne sais pas comment le faire efficacement.

Merci!

76voto

Jason Points 125291

Lire à la fin du fichier, puis chercher vers l'arrière jusqu'à ce que vous trouver une dizaine de retours à la ligne, puis de les lire avant la fin en prenant en considération les différents codages. Assurez-vous de traiter les cas où le nombre de lignes dans le fichier est inférieur à dix. Ci-dessous est une mise en œuvre (en C# comme marqués ce), généralisée pour trouver le dernier numberOfTokens le fichier situé à l' path codé en encoding où le jeton séparateur est représenté par tokenSeparator; le résultat est renvoyé en tant que string (ce qui pourrait être amélioré par le retour d'un IEnumerable<string> qui énumère les jetons).

public static string ReadEndTokens(string path, Int64 numberOfTokens, Encoding encoding, string tokenSeparator) {

    int sizeOfChar = encoding.GetByteCount("\n");
    byte[] buffer = encoding.GetBytes(tokenSeparator);


    using (FileStream fs = new FileStream(path, FileMode.Open)) {
        Int64 tokenCount = 0;
        Int64 endPosition = fs.Length / sizeOfChar;

        for (Int64 position = sizeOfChar; position < endPosition; position += sizeOfChar) {
            fs.Seek(-position, SeekOrigin.End);
            fs.Read(buffer, 0, buffer.Length);

            if (encoding.GetString(buffer) == tokenSeparator) {
                tokenCount++;
                if (tokenCount == numberOfTokens) {
                    byte[] returnBuffer = new byte[fs.Length - fs.Position];
                    fs.Read(returnBuffer, 0, returnBuffer.Length);
                    return encoding.GetString(returnBuffer);
                }
            }
        }

        // handle case where number of tokens in file is less than numberOfTokens
        fs.Seek(0, SeekOrigin.Begin);
        buffer = new byte[fs.Length];
        fs.Read(buffer, 0, buffer.Length);
        return encoding.GetString(buffer);
    }
}

22voto

ctacke Points 53946

Je l'ouvrirais probablement comme un flux binaire, chercherais jusqu'au bout, puis reculer à la recherche de sauts de ligne. Sauvegardez 10 (ou 11 en fonction de la dernière ligne) pour trouver vos 10 lignes, puis lisez jusqu'à la fin et utilisez Encoding.GetString sur ce que vous avez lu pour le convertir en format chaîne. Diviser comme vous le souhaitez.

17voto

w4g3n3r Points 808

Queue? Tail est une commande unix qui affiche les dernières lignes d’un fichier. Il existe une version Windows dans le kit de ressources Windows 2003 Server .

17voto

Jon Skeet Points 692016

Comme les autres l'ont suggéré, vous pouvez aller à la fin du fichier et lire à l'envers, de manière efficace. Cependant, c'est un peu délicat, en particulier parce que si vous avez un codage de longueur variable (tel que UTF-8), vous devez être rusé pour vous assurer d'obtenir des caractères "entiers".

6voto

Lolindrath Points 1779

Vous devriez pouvoir utiliser FileStream.Seek () pour aller à la fin du fichier, puis revenir en arrière, en recherchant \ n jusqu'à ce que vous ayez assez de lignes.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X