2013-04-12 2 views
4

매우 큰 ascii 파일을 "매핑"하려고합니다. 기본적으로 특정 태그를 찾을 때까지 줄을 읽은 다음 해당 태그의 위치를 ​​알고 나중에 관련 데이터를 꺼내기 위해 다시 찾을 수 있습니다.파일 객체의 버퍼 크기를 찾는 방법이 있습니까?

from itertools import dropwhile 
with open(datafile) as fin: 
    ifin = dropwhile(lambda x:not x.startswith('Foo'), fin) 
    header = next(ifin) 
    position = fin.tell() 

이제이 tell이 올바른 위치를 제공하지 않습니다. 이 질문은 다양한 형태로 이전에 요청되었습니다. 그 이유는 아마도 파이썬이 파일 객체를 버퍼링하기 때문일 것입니다. 그래서 파이썬은 파일 포인터가 어디에 있는지 알려주고 파일 포인터는 어디에 있는지 알려줍니다. I don't want to turn off this buffering ... 여기 성능이 중요합니다. 그러나, 파이썬이 얼마나 많은 바이트를 버퍼링할지 결정하는 방법이 있는지를 아는 것이 좋다. 제 실제 적용에서, 제가 Foo으로 시작하는 줄을 닫는 한 그것은 중요하지 않습니다. 나는 여기 저기에 몇 줄을 떨어 뜨릴 수있다. 버퍼 크기를 찾는 것에 대해 갈 수있는 방법이

position = fin.tell() - buffer_size(fin) 

가있다 : 그래서, 실제로 일을 계획하고있어이 같은입니까?

+0

여기서 ftell()을 사용하는 대신 건너 뛸 행의 길이를 합산합니다. –

+0

@RussellBorogove - 원래 생각한 합리적인 접근 방식이지만, 단점은 '지느러미'에서 아무것도 읽지 않았다고 가정해야한다는 것입니다. 사실, 입력 매개 변수로'fin'을받는 함수에서 이것을 호출하려고합니다. – mgilson

답변

2

내게는 Cpython에서 버퍼 크기가 hard-coded 인 것처럼 보입니다. 8192가 될 수 있습니다. 내가 말할 수있는 한, 파이썬 인터페이스에서이 번호를 얻는 방법은 없습니다. 단 한 줄만 읽으면됩니다. 파일을 읽으려면 f.tell()을 수행하여 실제로 얼마나 많은 양의 데이터를 읽었는지 파악한 다음 계속하기 전에 파일의 시작 부분을 찾으십시오. 물론

with open(datafile) as fin: 
    next(fin) 
    bufsize = fin.tell() 
    fin.seek(0) 

    ifin = dropwhile(lambda x:not x.startswith('Foo'), fin) 
    header = next(ifin) 
    position = fin.tell() 

,이 첫 번째 줄 이상 8192 바이트보다 긴하는 경우에 실패,하지만 내 응용 프로그램에 대한 실제 결과의 아니에요.

+0

'open'은 파일의 버퍼 크기를 설정하는 선택적'buffering' 인수를 취합니다. 이것이 하드 코딩 된 버퍼 크기와 어떻게 관련이 있는지 알고 있습니까? 그들은 다른 완충제인가? – Emily

+0

@Emily - 좋은 질문입니다. 나는 실제로 확신하지 못한다. 어쩌면 내가보기보다 C 소스를 잘 아는 사람이 필요합니다 ... – mgilson

+0

글쎄, 이제 나는 궁금해서 새로운 질문을 시작했습니다 : http://stackoverflow.com/questions/15991702/what-is 차이점은 - 버퍼링 - 인수 - 오픈 -와 - 하드 코드는 그동안 소스를 파고 계속 ... – Emily

관련 문제