스트림(Stream) 이란?
스트림이란 영어로는 '흐름'을 뜻하는 단어로서 프로그램의 입력과 출력을 바이트(byte)들의 흐름으로 생각하는 것입니다. C언어에서는 FILE이라는 구조체의 포인터인 FILE* 로 스트림을 구현하고 있습니다. 표준 입출력 스트림으로는 (Standard의 줄임말인 std를 붙인) stdin, stdout, stderr 가 있습니다. stdin은 키보드의 입력, stdout과 stderr는 모니터로의 출력을 지원합니다. stdio 헤더 파일로 터미널에서 표준 입출력을 많이 사용해 보셨을텐데요, 이제부터는 표준 입출력을 벗어나 이진 파일(Binary File)에 접근하여 입출력을 해볼 것 입니다.
파일(File) 이란?
C에서 파일의 정의는 바이트들의 집합입니다. 무슨 파일이던 컴퓨터에서 열리는 것은 이진 체계를 기반으로 하기 때문입니다. 파일의 종류에는 텍스트 파일과 텍스트 파일을 제외한 다른 모든 파일을 일컫는 이진 파일, 총 두 가지가 있습니다. ASCII 코드를 기반으로 작성된 문자 파일(.txt, .c 등)을 텍스트 파일이라고 하며 무언가 실행하는 .exe 파일, 음성 정보를 저장한 .mp3 등 텍스트 파일을 제외한 파일을 이진 파일이라고 합니다. 이러한 다양한 형태의 이진 파일은 특정 프로그램에 의해서만 해독이 가능한데, 예를 들면 .docx 파일을 한글로 열려고 하면 열리긴 하지만 글자가 깨지거나 단락이 잘못되는 경우가 있습니다. 이는 .docx 파일은 워드라는 특정 프로그램을 이용해야 정상적인 사용이 가능하기 때문입니다.
C에서 파일 열고 닫기
이제 실제로 파일을 열고 닫아보도록 하겠습니다. 파일을 여는 함수인 fopen() 함수는 위에 말씀드린 스트림의 FILE*(파일 구조체 포인터)를 반환하는 함수입니다. 이 함수는 인자로 파일 경로와 파일 열기 모드를 받습니다.
다음은 파일 모드에 대한 표입니다.
r |
읽기 모드로 파일을 엽니다. 파일이 없으면 오류를 출력하고 NULL 포인터를 반환합니다. |
w |
쓰기 모드로 새로운 파일을 생성합니다. 기존에 같은 이름의 파일이 존재한다면 삭제됩니다. |
a |
append(추가) 모드로, 기존 파일의 끝에서부터 데이터를 추가하며 만약 파일이 없다면 새로 생성합니다. |
r+ |
(+가 붙으면 수정 모드라고 하여 읽기와 쓰기가 모두 가능해집니다.) 읽기 모드로 파일을 열지만 쓰기 모드로 전환할 수 있습니다. 파일이 없으면 오류를 출력하고 NULL 포인터를 반환합니다. |
w+ |
쓰기 모드로 열되, 읽기 모드로 전환 가능합니다. 새로운 파일을 만들며 기존 파일의 내용은 삭제됩니다. |
a+ |
추가 모드로 열되, 읽기 모드로 전환 가능합니다. 새로 데이터를 추가하면 EOF(End of File)을 새로운 데이터 뒤로 옮깁니다. 만약 파일이 없다면 새로 생성합니다. |
t |
텍스트 파일 모드로 파일을 엽니다. |
b |
이진 파일 모드로 파일을 엽니다. |
* 이 중 t와 b 모드는 단일로 쓰이지 않고 rb+ 와 같이 다른 모드에 붙여 사용됩니다.
** b를 붙이지 않은 모드는 모두 .txt (텍스트 파일)에 대한 것입니다. 예를 들어 r 모드로 .bin 파일을 읽으려고 하면 안됩니다. rb 모드로 .bin 파일을 읽어야 합니다.
그럼 fopen() 를 사용해 파일을 열고 fclose() 로 파일을 닫는 프로그램을 작성해보겠습니다.
#include <stdio.h>
int main(void) {
// 읽기 모드 => 파일이 없으므로 NULL 포인터 반환
FILE* frp = fopen("thereisNOfile.txt", "r");
if (frp != NULL) {
printf("File is Opened Successfully\n");
}
else {
printf("File couldn't be opened\n");
}
// 쓰기 모드 => 새로운 파일 생성됨
FILE* fwp = fopen("example.txt", "w");
if (fwp != NULL) {
printf("File is Opened Successfully\n");
}
else {
printf("File couldn't be opened\n");
}
fclose(frp);
fclose(fwp);
return 0;
}
이렇게 fopen() 으로 파일을 열면 반환된 FILE* 를 새로운 스트림으로 사용할 수 있습니다. 다음 포스팅에서는 fscanf(), fprintf() 등의 함수들로 FILE* 을 사용해보도록 하겠습니다.
<참고자료>
https://www.ibm.com/docs/en/i/7.2?topic=functions-fopen-open-files#d22734e923