큰 파일을 한 줄씩 읽는 방법?


536

전체 파일의 각 줄을 반복하고 싶습니다. 이를 수행하는 한 가지 방법은 전체 파일을 읽고 목록에 저장 한 다음 관심있는 행을 넘어가는 것입니다. 이 방법은 많은 메모리를 사용하므로 대안을 찾고 있습니다.

지금까지 내 코드 :

for each_line in fileinput.input(input_file):
    do_something(each_line)

    for each_line_again in fileinput.input(input_file):
        do_something(each_line_again)

이 코드를 실행하면 오류 메시지가 나타 device active납니다..

어떤 제안?

목적은 파일의 각 줄에 대한 쌍별 문자열 유사성을 계산하는 것입니다. 다른 모든 줄과의 Levenshtein 거리를 계산하고 싶습니다.


4
각 줄마다 전체 파일을 다시 읽어야하는 이유는 무엇입니까? 어쩌면 누군가가 달성하려고하는 것을 말하면 더 나은 접근법을 제안 할 수 있습니다.
JJJ

답변:


1269

파일을 읽는 올바른 완전 Pythonic 방법은 다음과 같습니다.

with open(...) as f:
    for line in f:
        # Do something with 'line'

with열고 예외 이너 블록에서 발생되는 경우를 포함하여, 파일을 닫는 문 손잡이. 이 for line in f파일 객체 f는 반복 가능한 파일 객체 로 취급되며 버퍼링 된 I / O 및 메모리 관리를 자동으로 사용하므로 큰 파일에 대해 걱정할 필요가 없습니다.

그것을 할 수있는 분명한 방법이 하나 있어야합니다.


14
긍정이 파이썬 2.6 이상 최선 버전 인
시몬 Bergot

3
저는 개인적으로 데이터 파이프 라인을 다루기 위해 제너레이터와 코 루틴을 선호합니다.
jldupont

4
파일이 거대한 텍스트 파일이지만 한 줄로되어 있고 단어를 처리하는 것이 가장 좋은 전략은 무엇입니까?
mfcabrera

4
누군가 어떻게 for line in f:작동 하는지 설명 할 수 있습니까? 파일 객체를 어떻게 반복 할 수 있습니까?
haccks

11
객체를 반복하면 Python은 객체 메소드 목록에서이라는 특수 메소드 __iter__를 찾아서 수행 할 작업을 알려줍니다. 파일 객체는이 특별한 메소드를 정의하여 행을 통해 반복자를 반환합니다. (거의)
Katriel 12

130

순위가 높은 두 가지 메모리 효율적인 방법 (첫 번째가 가장 좋음)-

  1. 사용 with-Python 2.5 이상에서 지원
  2. yield당신이 정말로 읽을 양을 제어하고 싶다면 사용

1. 사용 with

with큰 파일을 읽는 훌륭하고 효율적인 파이썬 방법입니다. 장점-1) with실행 블록 을 종료 한 후 파일 객체가 자동으로 닫힙니다 . 2) with블록 내부의 예외 처리 . 3) 메모리 for루프는 f파일 객체를 한 줄씩 반복 합니다. 내부적으로 버퍼링 된 IO (비용이 많이 드는 IO 작업에 최적화) 및 메모리 관리를 수행합니다.

with open("x.txt") as f:
    for line in f:
        do something with data

2. 사용 yield

때로는 각 반복에서 읽을 양을보다 세밀하게 제어하기를 원할 수 있습니다. 이 경우 iter & yield를 사용하십시오 . 이 방법을 사용하면 마지막에 파일을 명시 적으로 닫아야합니다.

def readInChunks(fileObj, chunkSize=2048):
    """
    Lazy function to read a file piece by piece.
    Default chunk size: 2kB.
    """
    while True:
        data = fileObj.read(chunkSize)
        if not data:
            break
        yield data

f = open('bigFile')
for chuck in readInChunks(f):
    do_something(chunk)
f.close()

함정과 완전성을 위해 -아래 방법은 큰 파일을 읽는 데 좋지 않거나 우아하지 않지만 둥근 이해를 위해 읽으십시오.

파이썬에서 파일에서 행을 읽는 가장 일반적인 방법은 다음을 수행하는 것입니다.

for line in open('myfile','r').readlines():
    do_something(line)

그러나이 작업이 완료되면 readlines()함수 (기능에 동일하게 적용됨 read())가 전체 파일을 메모리에로드 한 다음 반복합니다. 큰 파일에 대해 약간 더 나은 방법 (처음 언급 한 두 가지 방법이 가장 좋습니다)은 fileinput다음과 같이 모듈 을 사용하는 것입니다.

import fileinput

for line in fileinput.input(['myfile']):
    do_something(line)

fileinput.input()호출은 행을 순차적으로 읽지 만 file파이썬에서 반복 할 수 있기 때문에 읽거나 읽은 후에도 메모리에 보관하지 않습니다 .

참고 문헌

  1. 문장이있는 파이썬

9
-1 기본적으로 결코 좋은 생각이 아닙니다 for line in open(...).readlines(): <do stuff>. 왜 네가?! 파이썬의 영리한 버퍼 반복자 IO의 이점을 모두 얻지 못했습니다.
Katriel

5
@Srikar : 문제에 대한 모든 가능한 해결책을 제시 할 시간과 장소가 있습니다. 초보자에게 파일 입력 방법을 가르치는 것은 아닙니다. 오답으로 가득 찬 긴 글의 맨 아래에 정답을 묻어 두는 것은 좋은 가르침이되지 않습니다.
Katriel

6
@Srikar : 올바른 방법으로 맨 위에 올린 다음 readlines왜 좋지 않은 이유 (파일을 메모리로 읽어들이므로) 를 언급 하고 설명한 다음 fileinput모듈이하는 일과 이유 를 설명 하면 게시물을 크게 개선 할 수 있습니다 다른 방법으로 사용하고 싶을 때 파일 청크가 어떻게 IO를 향상시키는 지 설명하고 청크 기능의 예를 제공합니다 (그러나 파이썬이 이미 당신을 위해 이것을 수행하므로 필요하지 않습니다). 그러나 간단한 문제를 해결하기위한 다섯 가지 방법을 제공하는 것만으로는이 중 4 가지가 잘못됩니다.
Katriel

2
완전성을 위해 무엇을 추가하든 먼저 추가하지 말고 마지막에 추가하십시오. 먼저 올바른 방법을 보여주십시오.
m000

6
@katrielalex는 내 대답을 다시 방문하여 구조 조정이 필요하다는 것을 알았습니다. 이전 답변이 어떻게 혼란을 일으킬 수 있는지 알 수 있습니다. 희망적으로 이것은 미래의 사용자에게 분명하게 될 것입니다.
Srikar Appalaraju

37

줄 바꿈을 제거하려면 :

with open(file_path, 'rU') as f:
    for line_terminated in f:
        line = line_terminated.rstrip('\n')
        ...

함께 보편적 인 개행 지원 모든 텍스트 파일 행이 종료 될 것처럼 보일 '\n'어떤 파일의 터미네이터,, '\r', '\n', 또는 '\r\n'.

편집- 범용 개행 지원을 지정하려면 다음을 수행하십시오.

  • 유닉스에서 파이썬 2--open(file_path, mode='rU') 필수 [감사합니다 @Dave ]
  • Windows의 Python 2-- open(file_path, mode='rU')옵션
  • 파이썬 3-- open(file_path, newline=None)옵션

newline매개 변수는 Python 3에서만 지원되며 기본값은 None입니다. 이 mode매개 변수 'r'는 모든 경우에 기본값 입니다. 는 U다른 메커니즘이 번역 나타나는 윈도우에서 파이썬 3에서 파이썬 2에서 더 이상 사용되지 않습니다 \r\n\n.

문서 :

기본 줄 종결자를 유지하려면

with open(file_path, 'rb') as f:
    with line_native_terminated in f:
        ...

이진 모드는 여전히 파일을로 줄을 분석 할 수 있습니다 in. 각 줄에는 파일에있는 모든 종결자가 있습니다.

감사합니다 @katrielalex대답 , 파이썬의 개방 () 문서 및 iPython의 실험.


1
Python 2.7에서는 open(file_path, 'rU')보편적 인 줄 바꿈을 활성화 해야했습니다 .
Dave

17

이것은 파이썬에서 파일을 읽는 가능한 방법입니다.

f = open(input_file)
for line in f:
    do_stuff(line)
f.close()

전체 목록을 할당하지 않습니다. 그것은 라인을 반복합니다.


2
이것이 작동하는 동안, 그것은 정식 방법이 아닙니다. 정식 방법은와 같은 컨텍스트 래퍼를 사용하는 것 with open(input_file) as f:입니다. 이것은 당신을 저장 f.close()하고 실수로 닫는 것을 잊지 않도록합니다. 파일을 읽을 때 메모리 누수 및 모두를 방지합니다.
마스트

1
@Mast가 말했듯이, 그것은 정식 방법이 아니므로 그렇게 공감하십시오.
azuax

12

내가 어디에서 왔는지에 대한 몇 가지 맥락. 코드 스 니펫이 끝났습니다.

가능하면 H2O와 같은 오픈 소스 도구를 사용하여 초 고성능 병렬 CSV 파일 읽기를 선호하지만이 도구는 기능 세트에 제한이 있습니다. 지도 학습을 위해 H2O 클러스터에 공급하기 전에 데이터 과학 파이프 라인을 만들기 위해 많은 코드를 작성하게되었습니다.

멀티 프로세싱 라이브러리의 풀 객체 및 맵 기능으로 많은 병렬 처리를 추가하여 UCI 리포지토리에서 8GB HIGGS 데이터 세트와 40GB CSV 파일과 같은 파일을 데이터 과학 목적으로 훨씬 빠르게 읽었습니다. 예를 들어 가장 가까운 이웃 검색을 사용하는 클러스터링과 DBSCAN 및 Markov 클러스터링 알고리즘은 심각하게 어려운 메모리 및 월 클럭 시간 문제를 우회하기 위해 병렬 프로그래밍 기술이 필요합니다.

나는 보통 gnu 도구를 사용하여 파일을 행 단위로 나누고 python 프로그램에서 병렬로 파일을 찾아서 읽을 수 있도록 glob-filemask합니다. 나는 일반적으로 1000+ 부분 파일과 같은 것을 사용합니다. 이러한 트릭을 수행하면 처리 속도 및 메모리 제한에 크게 도움이됩니다.

pandas dataframe.read_csv는 단일 스레드이므로 병렬 실행을 위해 map ()을 실행하여 팬더를 훨씬 빠르게 만들기 위해 이러한 트릭을 수행 할 수 있습니다. htop을 사용하여 일반 오래된 순차 팬더 dataframe.read_csv를 사용하면 하나의 코어에서 100 % CPU가 디스크가 아닌 pd.read_csv의 실제 병목 현상임을 알 수 있습니다.

SATA6 버스에서 회전하는 HD가 아니라 16 개의 CPU 코어가 아닌 빠른 비디오 카드 버스에서 SSD를 사용하고 있습니다.

또한 일부 응용 프로그램에서 훌륭하게 작동하는 것으로 밝혀진 또 다른 기술은 하나의 큰 파일을 여러 부분 파일로 사전 분할하는 대신 하나의 거대한 파일 내에서 병렬 CSV 파일 읽기를 수행하여 파일마다 다른 오프셋에서 각 작업자를 시작하는 것입니다. 각 병렬 작업자에서 python의 seek () 및 tell ()을 사용하여 큰 텍스트 파일을 큰 파일의 다른 바이트 오프셋 시작 바이트 및 끝 바이트 위치에서 동시에 동시에 읽을 수 있습니다. 바이트에서 정규식 찾기를 수행하고 줄 바꿈 수를 반환 할 수 있습니다. 이것은 부분 합계입니다. 마지막으로 작업자가 완료 한 후지도 함수가 반환 될 때 전체 합계를 얻기 위해 부분 합계를 합산합니다.

다음은 병렬 바이트 오프셋 트릭을 사용하는 예제 벤치 마크입니다.

나는 2 개의 파일을 사용합니다 : HIGGS.csv는 8GB입니다. UCI 기계 학습 저장소에서 제공됩니다. all_bin .csv는 40.4GB이며 현재 프로젝트에서 가져온 것입니다. 나는 리눅스와 함께 제공되는 GNU wc 프로그램과 내가 개발 한 순수한 python fastread.py 프로그램의 두 가지 프로그램을 사용한다.

HP-Z820:/mnt/fastssd/fast_file_reader$ ls -l /mnt/fastssd/nzv/HIGGS.csv
-rw-rw-r-- 1 8035497980 Jan 24 16:00 /mnt/fastssd/nzv/HIGGS.csv

HP-Z820:/mnt/fastssd$ ls -l all_bin.csv
-rw-rw-r-- 1 40412077758 Feb  2 09:00 all_bin.csv

ga@ga-HP-Z820:/mnt/fastssd$ time python fastread.py --fileName="all_bin.csv" --numProcesses=32 --balanceFactor=2
2367496

real    0m8.920s
user    1m30.056s
sys 2m38.744s

In [1]: 40412077758. / 8.92
Out[1]: 4530501990.807175

약 4.5GB / s (45Gb / s) 파일 슬러 핑 속도입니다. 내 친구 친구, 하드 디스크가 회전하지 않습니다. 실제로 삼성 Pro 950 SSD입니다.

다음은 순수한 C 컴파일 프로그램 인 gnu wc에 의해 동일한 파일에 대한 속도 벤치 마크입니다.

멋진 점은 순수한 파이썬 프로그램 이이 경우 gnu wc 컴파일 된 C 프로그램의 속도와 본질적으로 일치한다는 것을 알 수 있습니다. 파이썬은 해석되지만 C는 컴파일되므로 속도가 매우 흥미 롭습니다. 나는 당신이 동의 할 것이라고 생각합니다. 물론, wc는 실제로 병렬 프로그램으로 변경되어야하며, 실제로 파이썬 프로그램에서 양말을 이길 것입니다. 그러나 오늘날에도 gnu wc는 순차적 인 프로그램입니다. 당신은 당신이 할 수있는 일을하고, 파이썬은 오늘날 병렬 할 수 있습니다. Cython 컴파일은 나를 도울 수 있습니다 (다른 시간 동안). 또한 메모리 매핑 파일은 아직 탐색되지 않았습니다.

HP-Z820:/mnt/fastssd$ time wc -l all_bin.csv
2367496 all_bin.csv

real    0m8.807s
user    0m1.168s
sys 0m7.636s


HP-Z820:/mnt/fastssd/fast_file_reader$ time python fastread.py --fileName="HIGGS.csv" --numProcesses=16 --balanceFactor=2
11000000

real    0m2.257s
user    0m12.088s
sys 0m20.512s

HP-Z820:/mnt/fastssd/fast_file_reader$ time wc -l HIGGS.csv
11000000 HIGGS.csv

real    0m1.820s
user    0m0.364s
sys 0m1.456s

결론 : 속도는 C 프로그램에 비해 순수한 파이썬 프로그램에 적합합니다. 그러나 최소한 라인 계산 목적으로 C 프로그램보다 순수한 파이썬 프로그램을 사용하는 것만으로는 충분하지 않습니다. 일반적 으로이 기술은 다른 파일 처리에 사용될 수 있으므로이 파이썬 코드는 여전히 좋습니다.

질문 : 정규식을 한 번만 컴파일하고 모든 근로자에게 전달하면 속도가 향상됩니까? 답 : 정규식 사전 컴파일은이 응용 프로그램에서 도움이되지 않습니다. 그 이유는 모든 작업자의 프로세스 직렬화 및 생성 오버 헤드가 지배적이라고 생각합니다.

하나 더. 병렬 CSV 파일 읽기가 도움이 되나요? 디스크에 병목 현상이 있습니까, 아니면 CPU입니까? 스택 오버 플로우에 대한 많은 소위 최상위 답변에는 파일을 읽는 데 하나의 스레드 만 필요하다는 공통의 지혜가 포함되어 있습니다. 그래도 확실합니까?

알아 보자:

HP-Z820:/mnt/fastssd/fast_file_reader$ time python fastread.py --fileName="HIGGS.csv" --numProcesses=16 --balanceFactor=2
11000000

real    0m2.256s
user    0m10.696s
sys 0m19.952s

HP-Z820:/mnt/fastssd/fast_file_reader$ time python fastread.py --fileName="HIGGS.csv" --numProcesses=1 --balanceFactor=1
11000000

real    0m17.380s
user    0m11.124s
sys 0m6.272s

예, 그렇습니다. 병렬 파일 읽기는 아주 잘 작동합니다. 잘가요!

추신. 일부 작업자가 알고 싶어하는 경우 단일 작업자 프로세스를 사용할 때 balanceFactor가 2 인 경우 어떻게해야합니까? 글쎄, 끔찍하다.

HP-Z820:/mnt/fastssd/fast_file_reader$ time python fastread.py --fileName="HIGGS.csv" --numProcesses=1 --balanceFactor=2
11000000

real    1m37.077s
user    0m12.432s
sys 1m24.700s

fastread.py 파이썬 프로그램의 주요 부분 :

fileBytes = stat(fileName).st_size  # Read quickly from OS how many bytes are in a text file
startByte, endByte = PartitionDataToWorkers(workers=numProcesses, items=fileBytes, balanceFactor=balanceFactor)
p = Pool(numProcesses)
partialSum = p.starmap(ReadFileSegment, zip(startByte, endByte, repeat(fileName))) # startByte is already a list. fileName is made into a same-length list of duplicates values.
globalSum = sum(partialSum)
print(globalSum)


def ReadFileSegment(startByte, endByte, fileName, searchChar='\n'):  # counts number of searchChar appearing in the byte range
    with open(fileName, 'r') as f:
        f.seek(startByte-1)  # seek is initially at byte 0 and then moves forward the specified amount, so seek(5) points at the 6th byte.
        bytes = f.read(endByte - startByte + 1)
        cnt = len(re.findall(searchChar, bytes)) # findall with implicit compiling runs just as fast here as re.compile once + re.finditer many times.
    return cnt

PartitionDataToWorkers의 def는 일반적인 순차 코드입니다. 다른 사람이 병렬 프로그래밍이 어떤지 연습하고 싶어하는 경우에 대비하여 생략했습니다. 학습의 이점을 위해 테스트 및 병렬 코드를 제공하는 더 어려운 부분을 무료로 제공했습니다.

덕분에 : Arno와 Cliff와 H2O 직원의 오픈 소스 H2O 프로젝트는 훌륭한 소프트웨어 및 교육용 비디오를 제공하여 위와 같이이 순수한 파이썬 고성능 병렬 바이트 오프셋 리더에 영감을주었습니다. H2O는 java를 사용하여 병렬 파일 읽기를 수행하고, Python 및 R 프로그램에서 호출 할 수 있으며, 큰 CSV 파일을 읽을 때 지구상에서 가장 빠릅니다.


병렬 청크는 기본적으로 이것이 무엇인지입니다. 또한 SSD와 Flash가이 기술을 갖춘 유일한 호환 저장 장치라고 생각합니다. Spinning HD는 호환되지 않을 것입니다.
Geoffrey Anderson 18

1
OS 캐싱 디스크 파일을 어떻게 설명했습니까?
JamesThomasMoon1979

5

Katrielalex는 하나의 파일을 열고 읽는 방법을 제공했습니다.

그러나 알고리즘이 진행되는 방식에 따라 파일의 각 줄에 대한 전체 파일을 읽습니다. 즉 , N이 파일의 줄 수이면 파일을 읽는 전체 량과 레 벤슈 테인 거리 계산은 N * N이됩니다. 파일 크기가 걱정되고 메모리에 보관하고 싶지 않기 때문에 결과 2 차 런타임이 걱정 됩니다 . 알고리즘은 O (n ^ 2) 알고리즘 클래스에 있으며 전문화로 개선 할 수 있습니다.

메모리와 런타임의 트레이드 오프를 이미 알고 있다고 생각하지만 여러 Levenshtein 거리를 병렬로 계산하는 효율적인 방법이 있는지 조사하고 싶을 것입니다. 그렇다면 여기에서 솔루션을 공유하는 것이 흥미로울 것입니다.

파일에 몇 줄의 줄이 있고 알고리즘을 실행해야하는 컴퓨터 종류 (mem & cpu power)와 허용되는 런타임은 무엇입니까?

코드는 다음과 같습니다.

with f_outer as open(input_file, 'r'):
    for line_outer in f_outer:
        with f_inner as open(input_file, 'r'):
            for line_inner in f_inner:
                compute_distance(line_outer, line_inner)

그러나 문제는 거리 (매트릭스)를 어떻게 저장합니까? 예를 들어 처리를 위해 outer_line을 준비하거나 재사용을 위해 중간 결과를 캐싱하는 이점을 얻을 수 있습니다.


내 요점은이 게시물에는 질문에 대한 답변이 아니라 더 많은 질문이 포함되어 있다는 것입니다. IMO는 주석으로 더 적합합니다.
Katriel

1
@katriealex : 오류. 이상한. 중첩 된 루프를보고 실제 질문에 맞게 자신의 답변을 확장 했습니까? 내 답변에서 내 질문을 제거 할 수 있으며 아직 부분 답변으로 제공 할 수있는 충분한 내용이 있습니다. 질문에 명시 적으로 요청 된 중첩 루프 예제를 포함하도록 자신의 답변을 편집하면 수락 할 수 있으며 내 답변을 행복하게 제거 할 수 있습니다. 그러나 공감대는 내가 전혀 얻지 못한 것입니다.
cfi

그럴 수 있지; 질문에 대한 답변으로 중첩 된 for 루프를 시연하는 것을 실제로 보지 못하지만 초보자를 대상으로하는 것이 좋습니다. 공감 비가 제거되었습니다.
Katriel

3
#Using a text file for the example
with open("yourFile.txt","r") as f:
    text = f.readlines()
for line in text:
    print line
  • 읽을 파일을 엽니 다 (r)
  • 전체 파일을 읽고 각 줄을 목록 (텍스트)으로 저장하십시오.
  • 각 줄을 인쇄하는 목록을 반복합니다.

예를 들어, 특정 행을 10보다 큰 길이로 확인하려면 이미 사용 가능한 항목으로 작업하십시오.

for line in text:
    if len(line) > 10:
        print line

1
이 질문에 가장 적합하지는 않지만이 코드는 주로 찾고있는 것이 "slurping"(전체 파일을 한 번에 읽는) 경우에 유용합니다. 그건 내 사건이었고 구글이 나를 여기로 데려 갔다. +1. 또한 원 자성을 위해 또는 루프에서 시간 소모적 인 처리를하면 전체 파일을 읽는 속도가 더 빨라질 수 있습니다.
ntg

1
또한 코드를 약간 개선했습니다. 1. 다음과 같이 닫은 후에는 필요하지 않습니다. ( docs.python.org/2/tutorial/inputoutput.html , "with 키워드를 사용하는 것이 좋습니다 ..." 파일을 읽은 후 텍스트를 처리 할 수 ​​있습니다 (루프와 함께 ....)
ntg

2

fileinput .input ()에 대한 파이썬 문서에서 :

이것은에 나열된 모든 파일의 행을 반복 하며 목록이 비어 있으면 sys.argv[1:]기본값으로 설정 sys.stdin됩니다

또한 함수의 정의는 다음과 같습니다.

fileinput.FileInput([files[, inplace[, backup[, mode[, openhook]]]]])

줄 사이를 읽으면 files목록이 될 수 있으므로 다음과 같은 것을 가질 수 있습니다.

for each_line in fileinput.input([input_file, input_file]):
  do_something(each_line)

자세한 내용은 여기 를 참조하십시오


2

기본 파일 로딩은 엄청나게 느리므로 사용하지 않는 것이 좋습니다. numpy 함수와 IOpro 함수 (예 : numpy.loadtxt ())를 살펴 봐야합니다.

http://docs.scipy.org/doc/numpy/user/basics.io.genfromtxt.html

https://store.continuum.io/cshop/iopro/

그런 다음 pairwise 작업을 청크로 나눌 수 있습니다.

import numpy as np
import math

lines_total = n    
similarity = np.zeros(n,n)
lines_per_chunk = m
n_chunks = math.ceil(float(n)/m)
for i in xrange(n_chunks):
    for j in xrange(n_chunks):
        chunk_i = (function of your choice to read lines i*lines_per_chunk to (i+1)*lines_per_chunk)
        chunk_j = (function of your choice to read lines j*lines_per_chunk to (j+1)*lines_per_chunk)
        similarity[i*lines_per_chunk:(i+1)*lines_per_chunk,
                   j*lines_per_chunk:(j+1)*lines_per_chunk] = fast_operation(chunk_i, chunk_j) 

요소 단위로 데이터를로드하는 것보다 항상 청크 단위로 데이터를로드 한 다음 매트릭스 작업을 수행하는 것이 훨씬 더 빠릅니다 !!


0

마지막 위치 판독에서 큰 파일을 자주 읽어야합니까?

나는 하루에 여러 번 Apache access.log 파일을 자르는 데 사용되는 스크립트를 만들었습니다. 따라서 마지막 실행 중에 구문 분석 된 마지막 행에 위치 커서설정 해야했습니다 . 이를 위해 커서를 파일에 저장할 수있는 방법 file.seek()file.seek()방법을 사용했습니다.

내 코드 :

ENCODING = "utf8"
CURRENT_FILE_DIR = os.path.dirname(os.path.abspath(__file__))

# This file is used to store the last cursor position
cursor_position = os.path.join(CURRENT_FILE_DIR, "access_cursor_position.log")

# Log file with new lines
log_file_to_cut = os.path.join(CURRENT_FILE_DIR, "access.log")
cut_file = os.path.join(CURRENT_FILE_DIR, "cut_access", "cut.log")

# Set in from_line 
from_position = 0
try:
    with open(cursor_position, "r", encoding=ENCODING) as f:
        from_position = int(f.read())
except Exception as e:
    pass

# We read log_file_to_cut to put new lines in cut_file
with open(log_file_to_cut, "r", encoding=ENCODING) as f:
    with open(cut_file, "w", encoding=ENCODING) as fw:
        # We set cursor to the last position used (during last run of script)
        f.seek(from_position)
        for line in f:
            fw.write("%s" % (line))

    # We save the last position of cursor for next usage
    with open(cursor_position, "w", encoding=ENCODING) as fw:
        fw.write(str(f.tell()))

-2

큰 파일을 한 줄씩 읽는 가장 좋은 방법은 파이썬 열거 함수 를 사용하는 것입니다

with open(file_name, "rU") as read_file:
    for i, row in enumerate(read_file, 1):
        #do something
        #i in line of that line
        #row containts all data of that line

3
열거 형을 사용하는 것이 더 좋은 이유는 무엇입니까? 허용 된 답변에 대한 유일한 이점은 OP를 필요로하지 않고 코드를 읽을 수 없게 만드는 색인을 얻는 것입니다.
fuyas
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.