2009-08-10 5 views
2

나는 200.000 줄 이상의 큰 텍스트 파일을 가지고 있으며 몇 줄을 읽어야합니다. 예 : 줄 10.000 ~ 20.000.C++의 큰 텍스트 파일에서 부분 데이터를 읽는 방법

중요 : 성능 문제로 인해 논문 줄을 추출하려면 전체 파일을 열고 검색하고 싶지 않습니다.

이것이 가능합니까?

+0

Fortran에서는 데이터 카운터 (2 백만 라인)에서 파일을 읽어야했습니다. 그래서 나는 그것이 가능하다고 확신합니다. – dassouki

답변

1

모든 줄이 같은 길이라는 것을 알지 못하는 한, 파일을 검색하여 줄 바꿈을 계산해야합니다 (이 경우 오프셋 = line_number * line_size_in_bytes를 찾을 수 있습니다. 여기서 line_number는 0과 line_size_in_bytes가 포함됩니다). 줄의 모든 문자).

줄이 가변적/알 수없는 길이이면 한 번 읽는 동안 각 줄의 시작 오프셋을 인덱싱하여 후속 읽기가 주어진 줄의 시작을 찾을 수 있도록 할 수 있습니다.

6

줄이 고정 길이이면 특정 바이트 위치를 찾고 원하는 줄만로드 할 수 있습니다. 행이 가변 길이 인 경우 찾고있는 행을 찾는 유일한 f}은 파일을 구문 분석하고 행 끝 마커의 수를 계산하는 것입니다. 파일이 자주 변경되지 않으면이 구문 분석을 한 번 수행 한 다음 향후 액세스 속도를 높이기 위해 각 행의 바이트 위치 인덱스를 유지함으로써 충분한 성능을 얻을 수 있습니다 (아마도 인덱스를 디스크에 기록하여 프로그램이 실행될 때마다 완료됩니다.)

+1

주의 사항 : 일부 파일 형식에는 시작 부분에 인덱스가 있거나 끝 부분에 가끔 있습니다. 그런 다음 색인을 읽고이를 사용하여 필요한 데이터의 시작 위치를 계산합니다. 예, 바이너리 형식에서 더 쉽고 일반적입니다. 그러나 텍스트 형식으로 처리 된 것을 보았습니다. – dmckee

+0

+1 대답은 @dmckee : 초기 색인은 실제 문제가 아닌 것 같습니다. 결국에는 끝까지 탐색 할 수 있으며 인덱스 크기를 알고있을 수 있으므로 큰 문제는 아닌 것 같습니다. – neuro

+0

@neuro : 끝에있는 인덱스의 마지막 요소는 인덱스 시작 부분의 고정 크기 오프셋이어야합니다. 끝까지 추구하고, 알려진 양만큼 백업하고, 인덱스 오프셋을 읽고, 인덱스로 이동하여 거기에서부터 진행하십시오. 당연하지, 그렇지? :) – dmckee

0

이 줄이 모두 같은 길이이면 주어진 줄의 오프셋을 계산하고 그 줄만 읽을 수 있습니다.

줄의 길이가 다른 경우 줄 수를 계산하려면 전체 파일을 읽어야합니다. 줄 종료 문자는 파일의 임의의 바이트입니다.

0

선이 고정 길이이면 오프셋 만 계산하면 문제가 없습니다.

그렇지 않은 경우 (예 : 일반 CSV 파일) 색인을 작성하거나 필요한 줄을 읽으려면 파일을 거쳐야합니다. 파일을 좀 더 빨리 읽으려면 메모리 매핑 된 파일을 사용하는 것이 좋습니다 (Boost iostreams의 일부인 구현 : http://www.boost.org/doc/libs/1_39_0/libs/iostreams/doc/classes/mapped_file.html 참조).

0

다른 언급했듯이 너비가 고정 된 선이 없으면 색인을 작성하지 않고는 불가능합니다. 그러나 파일의 형식을 제어하는 ​​경우 라인 자체를 저장하는 경우 시작 행을 찾을 때 O (크기) 성능 대신 ~ O (로그 (크기))를 얻을 수 있습니다 각 라인, 즉 파일의 내용이 같은 것을 찾아 보게하기 : 파일의이 형식

1: val1, val2, val3 
2: val4 
3: val5, val6 
4: val7, val8, val9, val10 

를 신속 이진 검색하여 필요한 라인을 찾을 수 있습니다 : 파일의 중앙으로 추구로 시작합니다. 다음 줄 바꿈까지 읽으십시오. 그런 다음 줄을 읽고 번호를 파싱합니다. 숫자가 목표보다 크면 파일의 첫 번째 절반에서 알고리즘을 반복해야하며 목표 라인 번호보다 작 으면 파일의 두 번째 절반에서이를 반복해야합니다.

코너 케이스에주의해야합니다 (예 : 범위의 "시작"과 범위의 끝은 같은 라인에 있습니다). 그러나 나에게있어이 접근법은 과거에 날짜가있는 로그 파일을 구문 분석하기위한 과거 (그리고 특정 타임 스탬프 사이에있는 행을 찾아야했습니다).

물론 이것은 여전히 ​​명시 적으로 작성된 인덱스 또는 고정 크기 레코드의 성능을 능가하지는 않습니다.

관련 문제