Maison >développement back-end >Tutoriel Python >Comment récupérer efficacement les N dernières lignes d'un fichier volumineux ?

Comment récupérer efficacement les N dernières lignes d'un fichier volumineux ?

Patricia Arquette
Patricia Arquetteoriginal
2024-11-30 10:39:10422parcourir

How to Efficiently Retrieve the Last N Lines of a Large File?

Obtenir les N dernières lignes d'un fichier, en simulant la « queue »

Introduction :

Lors de l'analyse de fichiers journaux volumineux, il est souvent nécessaire de récupérer les N dernières lignes pour la pagination ou l'inspection. Cela soulève la question de savoir comment suivre efficacement un fichier journal avec un décalage.

Solution candidate 1 :

def tail(f, n, offset=0):
    avg_line_length = 74
    to_read = n + offset
    while 1:
        try:
            f.seek(-(avg_line_length * to_read), 2)
        except IOError:
            f.seek(0)
        pos = f.tell()
        lines = f.read().splitlines()
        if len(lines) >= to_read or pos == 0:
            return lines[-to_read:offset and -offset or None]
        avg_line_length *= 1.3

Évaluation :

Cette Cette approche fait des hypothèses sur la longueur moyenne des lignes et recherche progressivement en arrière jusqu'à ce qu'elle trouve suffisamment de lignes. En raison de l'estimation initiale, il peut être nécessaire de rechercher plusieurs fois, ce qui peut entraîner des pénalités de performance.

Solution candidate 2 :

def tail(f, lines=20):
    BLOCK_SIZE = 1024
    f.seek(0, 2)
    block_end_byte = f.tell()
    lines_to_go = lines
    block_number = -1
    blocks = []
    while lines_to_go > 0 and block_end_byte > 0:
        if (block_end_byte - BLOCK_SIZE > 0):
            f.seek(block_number * BLOCK_SIZE, 2)
            blocks.append(f.read(BLOCK_SIZE))
        else:
            f.seek(0, 0)
            blocks.append(f.read(block_end_byte))
        lines_found = blocks[-1].count('\n')
        lines_to_go -= lines_found
        block_end_byte -= BLOCK_SIZE
        block_number -= 1
    all_read_text = ''.join(reversed(blocks))
    return '\n'.join(all_read_text.splitlines()[-lines:])

Explication :

Cette méthode revient en arrière dans le fichier bloc par bloc jusqu'à ce qu'elle trouve le nombre souhaité de nouvelles lignes. Il ne fait pas d'hypothèses sur la longueur des lignes et lit depuis le début si le fichier est trop petit pour revenir en arrière.

Comparaison :

La solution candidate 2 est généralement plus efficace et robuste que la solution candidate 1. , car il ne s'appuie pas sur des estimations et lit le fichier de manière séquentielle. C'est une approche plus fiable pour suivre les fichiers journaux avec des décalages.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn