[파이썬 파일 읽기] 자료 구조 및 데이터 파일 읽기 - Whitmem
[파이썬 파일 읽기] 자료 구조 및 데이터 파일 읽기
Python Programming
2023-09-05 19:53 게시 89c05ff82a52b6d4bfd5

4
0
194
이 페이지는 외부 공간에 무단 복제할 수 없으며 오직 있는 그대로 게시되며 부정확한 내용을 포함할 수 있습니다. 법률이 허용하는 한 가이드 라인에 맞춰 게시 내용을 인용하거나 출처로 표기할 수 있습니다.
This page is not to be distributed to external services; it is provided as is and may contain inaccuracies.
파일 헤더
문서 파일이든 음악 파일이든 모든 파일은 바이너리 구조로 구성되어 있습니다. 각 개발자는 해당 파일로부터 의미있는 원시 데이터를 읽기 위해서는 해당 파일의 규격을 보고 정해진 방법에 따라 데이터를 읽어야 합니다.
예시
일상 생활로 예시를 들어보겠습니다 "제목""작성자""내용"으로 구성된 문서 파일이 있다고 가정하겠습니다. 여기서 제목, 작성자, 내용으로 구분을 하려면 어떻게 해야할까요?
사진 자료 1
기본적으로 이 문서만으로는 구별할 수 없습니다. 제목, 작성자, 내용을 구분할 수 있는 구분자가 없기 때문입니다. 따라서 ","를 기준으로 내용을 구별해야 합니다.
구분자 추가
한편 - 이 방법은 효율적인 방법은 아닙니다. 제목이나 내용이 반점에 들어가면 제목, 작성자, 내용을 구분할 수 없게 됩니다.
문제 발생
구분자와 내용이 충돌하게 되면, 해당 내용들을 분리할 수 있는 식별자의 의미를 잃게 되며, 데이터 읽기에 어려움을 겪게 됩니다. 게다가 매우 긴 문자열을 탐색해야 하는 경우에는 맨 앞에서 부터 순차적으로 ","라는 문자를 찾아가야 합니다. 이를 효율적으로 읽고 관리하기 위해서 "헤더"를 사용합니다.
헤더 예시
헤더 공간의 길이는 무조건적으로 고정한다고 약속하겠습니다. 헤더는 보통 실제 데이터가 존재하기 전 맨 앞에 위치하며, 그 어떠한 경우에도 길이는 무조건 고정되어 있기 때문에 실제 내용이 매우 길더라도 헤더의 길이는 절대 달라지지 않습니다.(보통의 경우에) 위 사진에서는 10자리를 규격으로 고정, 각 10자리에 제목의 길이, 작성자, 제목의 각 내용 길이를 순서대로기록 합니다.
헤더
위 문서를 읽기 위해서 맨 앞의 고정된 10자리를 읽어 제목의 길이를 가져옵니다. 다음으로 10자리를 읽어 작성자의 길이를 가져옵니다. 다음으로 10자리를 읽어 내용의 길이를 가져옵니다.
읽기 시작
이제 제목, 작성자, 내용의 길이가 각각 24 3 26이라는 사실을 알았습니다. 순서대로 24, 3, 26개 만큼 읽어주면 제목, 작성자, 내용을 읽을 수 있게 됩니다.
자료 구조의 경우
컴퓨터 자료로 표현할 때도 마찬가지 입니다. 위 문서의 내용과 동일하다고 가정하겠습니다. 이 문서는 "제목작성자내용"에 대한 헤더와 제목작성자내용 라는 내용을 순서대로 삽입 한 것 입니다.
자료
안타깝게도 위 실제 텍스트 문서 사례랑 다르게 컴퓨터에서는 10자리씩 구분짓지는 않습니다. 이는 자료 구조 방법에 따라 다릅니다. 차근 차근 따라가봅시다. 위 파일에 대해서 블록으로 표시 해 보겠습니다. 빨간색이 헤더 영역, 파란색이 실제 데이터 영역을 의미합니다.
설명
파란색에 실제로 "제목작성자내용" 이라는 우리말의 글자가 인코딩되어서 저장되어 있고, 우리는 이를 읽어 내기 위해서 먼저 제목 작성자 내용의 각각 "길이"에 대한 정보를 헤더로 부터 읽어내야 합니다.
설명
Hex 편집기에서, 두 개의 숫자는 무조건 1바이트를 의미합니다. 숫자 하나가 4비트 즉 0~F 까지의 범위 (16개의 경우의 수)를 표현합니다. 숫자 2개가 된다면 4비트 + 4비트로, 8비트 로 16*16 개의 경우의 수 = 256개의 경우의 수를 표현할 수 있는데 이를 컴퓨터에서는 1바이트로 표현합니다.
진수 정리 표
즉, HEX 에디터 프로그램에서는 16진수 숫자 하나를 2개씩 나열해서 한 바이트를 표시함에 유의해야 합니다.
hex 에디터
거의 모든 hex 프로그램은 읽기 편하도록 2글자씩 붙여서 표시 해 줍니다. 2개의 숫자가 결국 1바이트를 의미하기 때문입니다. 즉 위 바이트 내용이 전혀 이해가 안되더라도 걱정 할 필요 없습니다. 지금 당장은 숫자 2개가 무조건 1바이트라는 것만 알아두면 됩니다.
다시 돌아와서, 파일을 마저 읽어보겠습니다. 우선 파일을 읽기 전에 이 파일이 어떤 방식대로 구성된지 알아야 합니다. 보통 그러한 내용은 파일의 규격 문서에 포함되어 있습니다.
헤더 구조 오프셋 0 : Integer 32비트 - 제목의 길이 정보가 담겨있습니다. 오프셋 4 : Integer 32비트 - 작성자의 길이 정보가 담겨있습니다. 오프셋 8 : Integer 32비트 - 내용의 길이 정보가 담겨있습니다. 오프셋 12 : RAW - 실제 데이터의 원시 데이터입니다. 오프셋 ... :
그전에 위 이미지를 보면서 정리 합시다. 오프셋은 단순히 해당 지점의 바이트 위치(대부분 시작점)를 나타내는 용어이고, Integer 은 4바이트를 고정으로 하는 데이터형 "Int" 를 의미합니다. 제목, 작성자, 내용의 길이를 순서대로 읽기 위해서 헤더를 순서대로 읽어오면 됩니다. 이 파일의 규격 문서를 보면, 오프셋 0의 시작점에서는 Integer 32비트로, 제목의 길이 정보가 담겨있음을 알 수 있습니다. 즉 우리가 원하는 제목의 길이 정보가 오프셋 0번부터 Integer 바이트 형태로 저장되어 있다는 것으로, Integer의 길이인 4바이트를 읽어내면 됩니다.
파일 읽기 시작
파이썬에서 open 을 rp 모드로 열어 파일 읽기를 시작할 수 있습니다. 아직 아무런 읽기 작업을 진행하지 않았기 때문에 현재 지점은 오프셋 0 바이트입니다.
4바이트를 읽기
이번에는 title_len = _r.read(4)를 통해 4 바이트를 읽었습니다. 그로써 _r는 4 바이트를 읽었고, title_len 변수에 담겼습니다. 내부 읽기 지점은 이제 오프셋 4를 가르키게 됩니다. 한편 읽어들인 데이터는 바이트로 인코딩된 데이터인 "06 00 00 00"이므로, int 로 다시 decode 해야 합니다.
디코딩
파이썬에서는 struct의 unpack에 인자 integer를 의미하는 i 통해 디코딩할 수 있으며, 디코딩함으로써 "6"이라는 길이 숫자를 얻어냈습니다.
다음으로, 작성자 헤더를 의미하는 바이트 데이터도 읽어보겠습니다.
앞전에 4바이트를 읽었기 때문에 내부 오프셋은 4바이트를 가르키고 있습니다. 여기서 추가적으로 read(4)를 호출하여 작성자의 길이 정보를 읽어냅니다.
4바이트를 읽어내어 "09 00 00 00"을 읽어냈고, 이를 int로 디코딩한 결과 9라는 길이 정보를 얻어 냈습니다. 마저 내용의 길이도 읽어냅니다.
내용의 길이 역시 4바이트 int에 담겨 있기에 4바이트를 읽었고, 파일 읽기를 담당하는 _r의 내부 오프셋은 12번째 바이트를 가르키고 있습니다.
길이 정보
결과적으로 제목, 작성자, 내용의 길이를 모두 읽어들였습니다.
현재 상황
결과적으로 현재 제목, 작성자, 내용의 길이는 고정 4바이트이므로 4바이트씩 3번 읽었고, 파일 읽기 내부 오프셋은 실제 원시 데이터가 존재하는 위치에 도달했습니다. 이제 알아낸 제목의 길이 만큼, 작성자의 길이 만큼, 내용의 길이 만큼 순서대로 읽어내면 됩니다. 아까 헤더에서 디코딩하여 알아낸 제목의 길이를 title_len_int에 담아뒀습니다.
제목의 길이는 title_len_int에 담아뒀는데, struct.unpack 은 튜플 형태로 반환하기 때문에 [0] 번을 통해 6이라는 숫자를 가져왔습니다.이 6만큼 read() 해냄으로써 6바이트를 읽어냈고, 그 내용을 decode 하여 실제 제목의 데이터를 가져왔습니다.
실제 제목 데이터 6 바이트를 읽었기 때문에 현재 내부 오프셋은 18이 되었습니다. 마저 작성자와 내용도 같은 방법으로 읽어냅니다.
모두 제대로 완벽하게 읽어졌습니다. 기본적으로 네트워크 통신, 파일 구조 처리 등은 모두 이러한 내용을 기반으로 수행됩니다.
한편, CPU나 디바이스의 구조에 따라서 바이트가 쌓이는 방식이 달라질 수 있는데, 이 부분은 논외로 합니다.
댓글 0개
댓글은 일회용 패스워드가 발급되며 사이트 이용 약관에 동의로 간주됩니다.
확인
Whitmemit 개인 일지 블로그는 개인이 운영하는 정보 공유 공간으로 사용자의 민감한 개인 정보를 직접 요구하거나 요청하지 않습니다. 기본적인 사이트 방문시 처리되는 처리 정보에 대해서는 '사이트 처리 방침'을 참고하십시오. 추가적인 기능의 제공을 위하여 쿠키 정보를 사용하고 있습니다. Whitmemit 에서 처리하는 정보는 식별 용도로 사용되며 기타 글꼴 및 폰트 라이브러리에서 쿠키 정보를 사용할 수 있습니다.
이 자료는 모두 필수 자료로 간주되며, 사이트 이용을 하거나, 탐색하는 경우 동의로 간주합니다.