C언어 텍스트 파일과 바이너리 파일의 차이는?

2021. 3. 6. 04:59 컴퓨터/프로그래밍

바이너리 파일? 텍스트 파일?

C/C++ 언어를 학습하다 보면 파일 종류 중에 텍스트 파일과 바이너리 파일 얘기가 나오는데요, 처음 접하시는 분이라면 혼란스러울 수 있습니다. 설명하는 내용이 대부분 눈에 보이는 문자로 저장하는 것이 텍스트 파일이고 바이트 단위로 저장하는 것이 바이너리 파일이다라고 하는데요, 그렇다면 텍스트 파일은 바이트 단위로 저장하는 것이 아닌가요? 바이너리 파일을 열어보면 내용이 전혀 없는 빈 파일로 보일까요?

텍스트 파일과 바이너리 파일 모두 바이트 단위로 저장되며, 텍스트 에디터로 파일을 열었을 때 의미 있는 내용으로 읽을 수 있는지로 구분한다는 것은 100% 정확하다고 할 수 없지만, 대부분 이렇게 생각합니다. 완전하지 않다는 것은 한글 파일을 영문 전용 에디터로 열어 봤을 때 모두 깨져 보인다고 바이너리 파일일까요?

한글에 대해서는 의견이 다를 수 있습니다. ASCII 테이블에 있는 문자만 사용하는 것을 텍스트 파일이라고 주장하는 분이 있기 때문입니다. 한글은 완성형이냐 조합형이냐에 따라서 글자 하나가 바이트 2개 또는 3~4개로 구성되고 각 바이트는 코드 값을 대신하는 이진 데이터이기 때문에 텍스트라고 말할 수 없다는 것입니다. 흠.

그러나 한글이 두 바이트 이상이라고 하더라도 문자를 그대로 저장하는 것이므로 텍스트 파일이다라고 상반되는 말씀이 있으며 저도 동감합니다. 만일 한글을 ASCII 테이블에 없는 코드라고 해서 바이너리 데이터라고 생각한다면 정말이지 텍스트 파일을 구분하기는 매우 모호해지고 개발자끼리 대화도 힘들어집니다.

바이너리 파일은 2진 파일이므로 데이터 그대로 바이트 단위로 저장한다고 해서 텍스트 파일과 구별된다는 말씀도 이상합니다. ASCII 코드도 이진 코드이기 때문이지요.

텍스트 파일과 바이너리 파일의 차이는 파일로 저장하는 형태를 따지면 쉽게 이해할 수 있습니다. 예를 들어서 100(0x64)을 파일에 저장하려고 합니다. 텍스트 파일로 작성한다면 아래와 같이 프로그램을 작성하게 됩니다.

#include <stdio.h>

int main( void)
{
    FILE      *fp;
                                          
    fp  = fopen( "./text_file.txt", "w");
    fprintf( fp, "%d", 100);
    fclose( fp);

    return 0;
}

바이너리 파일로는 저장하는 경우는 아래와 같이 작성합니다.

#include <stdio.h>
#include <fcntl.h> 
#include <unistd.h>

int main( void)
{
   char   num = 100;
   int    fd;

   fd = open( "./binay_file.bin", O_WRONLY ¦ O_CREAT ¦ O_EXCL, 0644);
   write( fd, &num, 1);
   close( fd);
   return 0;
}

각 프로그램이 생성한 파일의 크기를 보면 아래와 같습니다. 100을 텍스트로 저장한 파일은 test_file.txt이고 바이너리로 만든 파일은 binary_file.bin입니다.

$ ls -al
합계 108
drwxr-xr-x 2 badayak badayak  4096  3월  2 17:03 .
drwxrwxr-x 4 badayak badayak  4096  9월 22 16:44 ..
-rw-r--r-- 1 badayak badayak     1  3월  2 17:03 binay_file.bin
-rw-r--r-- 1 badayak badayak     3  3월  2 17:01 text_file.txt
$

파일 크기가 다르죠? 저장된 모습은 어떨까요?

▲ 파일의 내용을 byte 값으로 보여 주는 프로그램으로 text_file.txt는 위와 같이 보입니다. 바이트 3개는 ASCII에 따라 0x31('1'), 0x30('0'), 0x30('0')이 됩니다.

▲ binary_file.txt는 0x64로 십진수로 100입니다.

▲ text_file.txt를 텍스트 에디터로 열었을 때의 모습입니다.

▲ binary_file.bin은 텍스트 에디터로는 100(0x64)의 ASCII 코드가 출력됩니다.

같은 숫자 100을 저장한다고 해도 텍스트 파일은 숫자 값을 저장하는 것이 아니라 읽을 수 있는 형태로 저장합니다. 바이너리 파일은 숫자 자체를 저장하는 것이죠.

즉, 텍스트 파일은 데이터 위주가 아니라 문서 파일로 읽기 가능한 형식으로 작성하는 파일이고 바이너리 파일은 데이터 형태 그대로 저장한다고 생각하는 것이 편합니다. 로그 데이터는 텍스트 에디터만으로 읽을 수 있으면 편할 것이므로 텍스트 파일로 저장하고, 이미지 음악·동영상·실행 파일 등은 파일 용량을 줄이고 빠르게 처리할 수 있도록 바이너리 파일로 저장하는 것이 효율적입니다.

이렇게도 생각할 수 있겠네요. 텍스트 파일을 사람을 위한 형식이고 바이너니 파일은 프로그램 또는 컴퓨터로 처리하기 편한 형식이라고 말이죠.

텍스트 통신, 바이너리 통신

텍스트와 바이너리는 비단 파일에만 국한되는 것이 아닙니다. 통신에서도 텍스트로 할지, 바이너리로 할지에도 사용됩니다. 텍스트 통신을 한다면 별도의 프로그램 없이도 수신하는 데이터를 바로 이해할 수 있습니다. 데이터를 더 쉽게 볼 수 있도록 엔터키를 삽입하는 경우도 많고 그 엔터키로 새로운 데이트 입력으로 구분합니다.

한 줄의 데이터로 나누어 처리하는 것이죠. 0x0d를 만나면 새로운 데이터의 시작입니다. 별다른 프로그램 없이도 수신된 내용 그대로 화면에 출력하면서 확인이 가능합니다.

온도:20 습도:80
온도:21 습도:82
온도:20 습도:80
온도:22 습도 80
       :

바이너리 통신은 각 바이트를 직접 확인해야 합니다. 바이트 단위로 온도/습도를 연속으로 보내 준다고 한다면 각 바이트가 의미하는 것을 따로 분석해야 합니다. 몇 번째 바이트인지 앞에서부터 숫자를 세가며 확인하는데 데이터가 많으면 눈으로는 힘들어서 프로그램을 작성하기도 합니다.

06 A7 06 A8 06 B0 08 A0 06 A7 06 A8 06 B0 08 A0 06 A7 06 A8 06 B0 08 A0 .....

이렇게 보면 바이너리 통신이 어렵게 보이지만, 텍스트 파일보다 전송할 데이터 량이 적고 구조화된 데이터를 한 번에 보내고 받을 수 있습니다.

typedef struct{
  int   sz_mque;
  int   id;
  int   cmd;
  int   sz_data;
  U16  data[MAX_SZ_DATA];
}STRUCT_PACK mque_item_t;

mque_item_t mque;
mque.sz_mque = sizeof( mque_item_t);
mque.id   = 100;
mque.cmd = CMD_SEND_DATA;
mque.sz_data = sz_data;
memcpy( mque.data, rcv_data, sz_data);
send( &mque, sizeof( mque_item_t));

수신하는 쪽에서도 데이터를 분석해서 변수로 나누어 주는 고단한 작업을 하지 않아도 struct의 포인터로 항목별 값을 확인할 수 있습니다.

U16 buff[4096];
mque_item_t *p_mque;

recieve_data( buff, sizeof(buff));
p_mque =( mque_item_t *)buff;
printf( "cmd=%d\n", p_mque->cmd);

구조화된 데이터라고 하더라도 반드시 바이너리로 통신하지는 않습니다. 텍스트 형태의 json 코드도 많이 사용됩니다.

{“cmd”:“open”, “target”:“door”, “list”:[{“id”:1}, {“id”:2}]}
{“cmd”:“close”, “target”:“door”, “list”:[{“id”:3}, {“id”:5}]}

전송할 데이터 양은 늘어도 디버깅하기가 매우 편합니다. 잘못 보냈는지, 제대로 처리를 못한 것인지 따질 일이 없습니다. 잘못한 부분이 바로 보이니까요.

어떻습니까? 텍스트 파일과 바이너리 파일의 차이점이 이해되시나요?

이 댓글을 비밀 댓글로

티스토리 로그인이 풀리면 여기를 클릭하세요.

error: Content is protected !!