문제

500MB> 500MB의 큰 로그 파일을 생성하는 응용 프로그램이 있습니다.

나는 로그 파일을 빠르게 탐색하고 관심있는 데이터를 찾을 수있는 일부 유틸리티를 Python으로 작성했습니다. 그러나 이제 파일이 너무 커서 모두 메모리에로드하기에는 일부 데이터 세트가 나타납니다.

따라서 문서를 한 번 스캔하고 인덱스를 작성한 다음 한 번에보고 싶은 문서 섹션 만 메모리에만로드하려고합니다.

이렇게하면 '파일'을 열면 한 번에 한 줄을 읽고 파일에서 오프셋을 저장하면 From File.tell ()을 저장합니다. 그런 다음 나중에 파일의 해당 섹션으로 돌아올 수 있습니다.

그러나 내 문제는 로그 파일에 UTF-8이있을 수 있으므로 Codecs 모듈로 열어야한다는 것입니다.codecs.open(<filename>, 'r', 'utf-8')). 결과적인 객체를 사용하면 Seek and Tell을 호출 할 수 있지만 일치하지 않습니다.

코덱이 약간의 버퍼링을해야한다고 가정하거나 Tell의 바이트 대신 문자 수를 반환 할 수 있습니까?

이것에 대한 방법이 있습니까?

도움이 되었습니까?

해결책

사실이라면, 이것은 코덱 모듈의 버그 또는 제한처럼 들리며, 바이트와 문자 오프셋이 혼란 스러울 것입니다.

나는 규칙을 사용할 것입니다 open() 그런 다음 파일을 열기위한 기능 seek()/tell() 항상 일관된 바이트 오프셋을 제공합니다. 읽고 싶을 때마다 사용하십시오 f.readline().decode('utf-8').

그래도 사용해주십시오 f.read() 함수는 다중 바이트 문자의 중간에 착륙 할 수 있으므로 UTF-8 디코딩 오류가 발생할 수 있습니다. readline() 항상 작동합니다.

이것은 당신을 위해 바이트 주문 마크를 투명하게 처리하지는 않지만, 로그 파일에 BOM이 없을 가능성이 있습니다.

다른 팁

UTF-8의 경우 실제로 Codecs.open으로 파일을 열 필요가 없습니다. 대신 파일을 먼저 바이트 문자열로 읽은 다음 개별 섹션을 해독하는 것이 좋습니다 (문자열에서 .decode 메소드를 호출). 줄 경계에서 파일을 깨는 것은 안전합니다. 분할하는 유일한 안전하지 않은 방법은 다중 바이트 캐릭터의 중간에있을 것입니다 (바이트 값> 128에서 인식 할 수 있음).

Python 3에서 UTF8과 함께 진행되는 대부분은 Python 3에서 어떻게 수행되었는지 살펴보면 의미가 있습니다. 경우 Python 3에서 다이브에서 파일 장을 읽으면 훨씬 더 의미가 있습니다. http://diveintopython3.org/files.html

그러나 그것의 부족은 그게 그것입니다 file.seek 그리고 file.tell 유니 코드 문자는 여러 바이트를 가져갈 수있는 반면 바이트 위치로 작업하십시오. 따라서, 당신이 할 경우 :

f.seek(10)
f.read(1)
f.tell()

당신은 쉽게 다른 것을 얻을 수 있습니다 17, 당신이 읽은 캐릭터의 길이에 따라.

업데이트 : Codec.open ()에 의해 반환 된 개체를 찾아/말할 수 없습니다. 일반 파일을 사용하고 읽은 후 문자열을 유니 코드로 디코딩해야합니다.

왜 작동하지 않는지 모르겠지만 작동하게 할 수는 없습니다. 예를 들어 추구는 한 번만 작동하는 것 같습니다. 그런 다음 파일을 닫고 다시 열어야합니다. 물론 유용하지 않습니다.

Tell은 문자 위치를 사용하지 않지만 스트림의 위치가 어디에 있는지 보여주지 않습니다 (아마도 기본 파일 객체가 디스크에서 읽는 곳).

따라서 아마도 어떤 종류의 기본 버퍼링 때문에, 당신은 그것을 할 수 없습니다. 그러나 독서 후 Deocding은 잘 작동하므로 가십시오.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top