2014-06-18 2 views
0

이 질문에 이미 답변하지 않았 으면 좋겠지 만 올바른 검색어를 찾을 수없는 것 같습니다.루비/파이썬의 로우 레벨 파일 처리

처음 몇 가지 배경 : 나는 표 형식의 텍스트 데이터 파일을 가지고 있으며 10GB로 쉽게 올라갈 수 있습니다. 컴퓨터를 처리하는 컴퓨터는 장치 처리 및 제어를 수행함에 따라 이미 긴 시간 동안의 데이터 수집 (최대 30-50MB/s)에서 많은 부하를 받고 있습니다. 따라서 디스크 공간과 액세스가 중요합니다. 공간 제약으로 인해 회전 디스크에서 SSD로 이동하지 않았습니다.

그러나 우리는 모든 데이터 포인트가 필요하지 않은 수집 된 데이터로 무엇인가를하려고합니다. 우리는 데이터를 줄이고 1000 번째 포인트를 모으기를 희망했습니다. 그러나 이러한 파일 (기가 바이트 각각)을로드하는 것은 라이브 수집 시스템을 방해 할 수 있으므로 받아 들일 수없는 디스크에 큰 부담을줍니다.

파일이 매우 잘 정의되어 있기 때문에 파일의 모든 n 번째 바이트 (또는 다른 방법)에 액세스 할 때 저수준 메서드를 사용할 수 있는지 궁금합니다 (두 개의 64 비트가 두 배로 각 행). 하드 드라이브가 조각화 될 수 있기 때문에 너무 낮은 수준의 액세스가 작동하지 않을 수 있음을 이해하지만 가장 좋은 방법/방법은 무엇입니까? 파이썬이나 루비의 솔루션을 선호하는데, 그 이유는 이것이 프로세싱이 수행 될 것이기 때문입니다. 이론적으로 R, C, 또는 Fortran에서도 작동 할 수 있습니다.

마지막으로 컴퓨터 또는 하드웨어 업그레이드는 옵션이 아니므로 시스템을 설정하는 데 수백 시간이 걸렸으므로 소프트웨어 변경 만 수행 할 수 있습니다. 그러나 장기 프로젝트가 될 수 있지만 텍스트 파일이 이러한 파일을 처리하는 가장 좋은 방법이 아닌 경우 다른 솔루션에도 사용할 수 있습니다.

EDIT : 우리는 50000 라인 (초)/초에서 500 만 라인/초까지 어디서든이 속도로 실행 가능하지 않습니다 (사용법에 따라 다름).

+1

왜 데이터를 데이터베이스에 직접 수집하지 않습니까? – MattDMo

+0

불행하게도 계측기 제어 및 수집 소프트웨어에는 엄청난 속도의 데이터베이스 인터페이스가 있습니다. 레코드를 만들려고하면 50ms가 걸리고 초당 5 백만 개의 레코드가 생성됩니다. 대용량 데이터 파일은 완료된 후에 BLOB에 저장할 수 있지만 데이터가 여러 시간 동안 실시간으로 수집되므로 문제가 해결되지 않습니다. – lswim

+1

어떤 OS를 사용하고 있습니까? 이것은 매우 흥미로운 질문입니다. –

답변

1

파일 개체에 대한 검색 및 읽기 방법을 사용하여 수행 할 수 있어야합니다. 이렇게하면 파일 스트림에서만 작업하게되므로 전체 파일이 메모리에로드되지 않습니다.

또한 파일이 잘 정의되어 있고 예측 가능하기 때문에 파일의 다음 레코드까지 N 바이트를 앞두고 탐색하는 데 문제가 없습니다.

다음은 예제입니다. http://dbgr.cc/o

위의 코드는 pretend_im_large.bin 가정
with open("pretend_im_large.bin", "rb") as f: 
    start_pos = 0 
    read_bytes = [] 

    # seek to the end of the file 
    f.seek(0,2) 
    file_size = f.tell() 

    # seek back to the beginning of the stream 
    f.seek(0,0) 

    while f.tell() < file_size: 
     read_bytes.append(f.read(1)) 
     f.seek(9,1) 


print read_bytes 

에 아래의 코드를 데모하는 내용을 가진 파일입니다

A00000000 
B00000000 
C00000000 
D00000000 
E00000000 
F00000000 

위 코드의 출력 :

['A', 'B', 'C', 'D', 'E', 'F'] 
+1

'f.seek()'는 중간 바이트를 읽지 못하도록 보장됩니까? 나는 이것이 매우 플랫폼에 의존하는 것이라고 생각합니다. f.seek()가 실제로 9 바이트를 읽지 않고 9 바이트 씩 진행하는 방법을 알고 있다면 나는 다소 놀랐습니다. –

+0

여기에 사용 된 파일 찾기를 지원하지 않는 플랫폼을 생각할 수 없습니다. 찾으면 알려줘? 배후에서 구현되는 방법에 관계없이, 요점은 전체 파일이 동시에 메모리에 읽히지 않으며 (전체 행도 아님) 요점입니다. 참고로 linux (http://linux.die.net/man/2/lseek)의'lseek' 메쏘드와 윈도우의'SetFilePointer' 메쏘드 (http://msdn.microsoft.com/en-us) /library/windows/desktop/aa365541(v=vs.85).aspx), Mac에서의 lseek 메소드 (https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/) man2/lseek.2.html) –

+0

근본적인 OS가 그것을 지원한다고해서 그것이'f.seek'가 그것을 활용하는 방식으로 구현되었다는 것을 의미하지는 않습니다. 필자는 Python이 OS 기능을 활용할 것이라는 보장을하지 않는다고 생각합니다. 따라서 기본 C 구현을 검토하거나 광범위한 테스트를 수행하지 않고도 OS 기능에 의존하는 것을 주저합니다. –

0

I 파이썬이 012를 사용할 때 실제로 전체 파일을 읽지 않을 것이라는 강력한 보장을 줄 것이라고 생각하지 마십시오.. 필자는 이것이 파이썬에 의존하기에는 너무 플랫폼적이고 구현에 따라 다르다고 생각합니다. 순차적이 아닌 임의의 액세스를 보장하는 Windows 전용 도구를 사용해야합니다.

Here's a snippet of Visual Basic 귀하가 필요에 맞게 수정할 수 있습니다. 두 개의 64 비트 정수가 긴 자체 레코드 유형을 정의 할 수 있습니다. 또는 C# FileStream object을 사용하고 seek 메소드를 사용하여 원하는 것을 얻을 수 있습니다.

성능에 중요한 소프트웨어 인 경우 원하는 작업을 수행하는 OS 기본 기능에 액세스해야합니다. 파이썬의 seek이 원하는 것을 수행 할 것이라는 것을 나타내는 참조를 찾을 수 없습니다. 당신이 그 길을가는 경우, 그것이해야 할 것처럼 보이는 것을 확실히하기 위해 그것을 테스트 할 필요가 있습니다.

0

파일을 사람이 읽을 수있는 텍스트 형식입니까, 컴퓨터의 기본 형식 (이진 파일이라고도 함)입니까? 파일이 텍스트이면 원시 형식으로 전환하여 처리로드 및 파일 크기를 줄일 수 있습니다. 부동 소수점 숫자의 내부 표현을 사람이 읽는 숫자로 변환하는 것은 CPU를 많이 사용합니다.

파일이 네이티브 형식이면 각 레코드가 16 바이트가되므로 파일을 건너 뛰기가 쉽습니다. Fortran에서 form="unformated", access="direct", recl=16을 포함하는 open 문으로 파일을 엽니 다. 그런 다음 read 문에서 rec=X을 통해 중간 레코드를 읽지 않고 임의의 레코드 X를 읽을 수 있습니다. 파일이 텍스트 인 경우 직접 IO로 읽을 수도 있지만 두 숫자가 항상 같은 수의 문자 (바이트)를 사용하지는 않습니다. 파일을 검사하고 그 질문에 대답 할 수 있습니다. 레코드가 항상 동일한 길이이면 form="formatted"과 동일한 기술을 사용할 수 있습니다. 기록의 길이가 다른 경우 큰 덩어리를 읽고 덩어리 내의 숫자를 찾을 수 있습니다.

관련 문제