Chercher à lire les n dernières lignes d'un fichier est une exigence courante, qui rappelle la queue -n commande dans les systèmes de type Unix. Pour y parvenir, nous devons trouver une méthode efficace capable de fournir cette fonctionnalité.
Une approche proposée consiste à estimer une longueur de ligne moyenne et à l'augmenter progressivement jusqu'à ce qu'elle soit suffisante. nombre de lignes sont lues. Cette méthode, bien que raisonnable, repose sur l'estimation de la longueur de la ligne et peut être moins performante dans certains scénarios.
Une méthode alternative plus robuste consiste à parcourir le fichier en blocs. La taille du bloc peut être ajustée pour des performances optimales et la méthode ne repose sur aucune hypothèse concernant la longueur de la ligne. Il continue à lire les blocs jusqu'à ce que le nombre total de lignes souhaitées soit obtenu. Cette technique garantit des performances cohérentes et fiables sur différentes tailles de fichiers et longueurs de ligne.
Lors de l'utilisation de cette méthode basée sur les blocs, il est important de prendre en compte la taille du fichier par rapport à celle du système. taille de bloc du système d’exploitation (OS). Si le fichier est plus petit qu'un seul bloc du système d'exploitation, la méthode peut entraîner des lectures redondantes et des performances inférieures. Dans de tels cas, l’alignement de la taille de bloc sur celle du système d’exploitation peut apporter des améliorations. Cependant, pour les fichiers volumineux, cette optimisation peut ne pas avoir d'impact significatif.
L'approche alternative proposée peut être implémentée en Python comme suit :
def tail(f, lines=20): """Reads the last n lines from a file.""" 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(b'\n') # Edit for Python 3.2 and up lines_to_go -= lines_found block_end_byte -= BLOCK_SIZE block_number -= 1 all_read_text = b''.join(reversed(blocks)) # Edit for Python 3.2 and up return b'\n'.join(all_read_text.splitlines()[-lines:]) # Edit for Python 3.2 and up
Cette implémentation permet de spécifier le nombre de lignes à lire, ce qui en fait une solution flexible et polyvalente. Il donne la priorité à la robustesse et aux performances, en évitant les hypothèses sur la longueur des lignes ou la taille des fichiers.
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!