>백엔드 개발 >파이썬 튜토리얼 >대용량 파일의 마지막 N 줄을 효율적으로 검색하는 방법은 무엇입니까?

대용량 파일의 마지막 N 줄을 효율적으로 검색하는 방법은 무엇입니까?

Patricia Arquette
Patricia Arquette원래의
2024-11-30 10:39:10438검색

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

'테일'을 시뮬레이션하여 파일의 마지막 N 줄 가져오기

소개:

대용량 로그 파일을 분석할 때, 페이지 매김이나 검사를 위해 마지막 N 줄을 검색해야 하는 경우가 많습니다. 이로 인해 오프셋을 사용하여 로그 파일을 효율적으로 추적하는 방법에 대한 의문이 제기됩니다.

후보 솔루션 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

평가:

이것은 접근 방식은 평균 라인 길이에 대한 가정을 하고 충분한 라인을 찾을 때까지 점진적으로 뒤로 탐색합니다. 초기 추정으로 인해 여러 번 탐색해야 할 수 있으며 잠재적으로 성능 저하가 발생할 수 있습니다.

후보 솔루션 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:])

설명:

이 방법은 원하는 수의 개행 문자를 찾을 때까지 파일 블록을 한 블록씩 역추적합니다. 줄 길이를 가정하지 않고 파일이 너무 작아 역추적할 수 없는 경우 처음부터 읽습니다.

비교:

후보 솔루션 2는 일반적으로 후보 솔루션 1보다 더 효율적이고 강력합니다. , 추정에 의존하지 않고 파일을 순차적으로 읽기 때문입니다. 오프셋을 사용하여 로그 파일을 추적하는 보다 안정적인 접근 방식입니다.

위 내용은 대용량 파일의 마지막 N 줄을 효율적으로 검색하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.