→ Posix: Portable Operating System Interface
→ File Descriptor
UNIX 및 UNIX-like 운영 체제에서 파일을 식별하고 접근하기 위한 정수형 식별자이다. file descriptor은 프로세스가 파일을 열거나 생성할 때 커널이 할당해 주는 고유한 식별자이다. 일반적으로는 정수값으로 표현되며 0 (표준입력), 1 (표준출력), 2(표준 에러)와 같은 의미를 가진다. 하지만 일반적으로 0,1,2 index는 std-in/std-out/error와 관련된 fd로 미리 할당되고 보통 open()을 호출하면 3을 리턴받게 된다.
→ Open file description
unix 및 unix-like 운영 체제에서 파일에 대한 메타데이터 및 상태정보를 저장하는 내부 데이터 구조이다. 파일이 열릴 때 커널에 의해 생성 되며, 해당 파일에 대한 정보를 추적하고 관리하는데 사용된다. Open file description은 다음과 같은 정보가 포함될 수 있다. Open file description은 파일을 참조하는 file descritor과 연결되어 있으며, 이를 통해 파일을 식별하고 조작할 수 있다. Open file description은 프로세스의 file table에 저장되어 있으며, 해당 파일을 다루는 데 필요한 정보들을 제공한다.
→ File Table: 커널이 관리하는 모든 열려진 테이블이다
Posix I/O 시스템 호출의 주요 목적
1.int open (const char *pathname, int flags, [mode_tmode]);
⇒ open() 함수는 file과 file descriptor간의 연결을 설정한다. 이 함수는 파일을 참조하는 open file description과 그 description을 참조하는 file descriptor을 생성하다. file descriptor은 다른 I/O 함수에서 해당 파일을 참조하는 데 사용된다.
‘pathname’: 열고자 하는 파일의 경로를 나타내는 문자열이다.
fcntl.h에 정의된 flag 상수 값 | |
---|---|
O_RDONLY | 읽기 전용으로 열기 |
O_WRONLY | 쓰기 전용으로 열기 |
O_RDWR | 읽기 및 쓰기 모드로 열기 |
O_CREAT | 파일이 존재하지 않으면 새로운 파일 생성하기 |
O_TRUNC | 파일을 열 때 기존 파일의 내용을 지우기 |
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main() {
// 파일 경로
const char *file_path = "example.txt";
// 파일을 읽기 전용으로 열기
int fd = open(file_path, O_RDONLY);
if (fd == -1) {
perror("open");
exit(EXIT_FAILURE);
}
// 파일 디스크립터 출력
printf("File descriptor: %d\n", fd);
// 파일을 읽기 전용으로 열었으므로 파일 내용을 읽을 수 있음
// 이후에는 파일을 다루는 작업을 수행할 수 있음
// 파일을 닫음
if (close(fd) == -1) { //파일을 닫는 동시에 에러가 나는지 확인한다.
perror("close");
exit(EXIT_FAILURE);
}
return 0;
}
int close(int fd);
⇒ 파일을 닫을 때 사용된다. 반환 값이 -1이면 파일을 닫는 도중 에러가 발생했음을 의미한다.
ssize_t read(int fd, void *buf, size_t count);
⇒ file descriptor가 가리키는 파일에서 데이터를 읽어오는 역할을 한다.
→ 만약 에러가 발생하면 -1을 반환하고, 더 이상 읽을 데이터가 없으면 0을 반환한다.
→ 만약 데이터 읽기에 성공하였으면, 읽어온 데이터의 크기를 반환한다.
→ tip. ssize_t는 signed size type의 약자, 부호있는 정수형의 크기를 나타냄.
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#define BUFFER_SIZE 1024
int main() {
int fd;
ssize_t bytes_read;
char buffer[BUFFER_SIZE];
// 파일 열기
fd = open("example.txt", O_RDONLY);
if (fd == -1) {
perror("open");
exit(EXIT_FAILURE);
}
// 파일에서 데이터 읽기
bytes_read = read(fd, buffer, BUFFER_SIZE);
if (bytes_read == -1) {
perror("read");
exit(EXIT_FAILURE);
}
// 읽은 데이터 출력
printf("Read %zd bytes: %s\n", bytes_read, buffer);
// 파일 닫기
if (close(fd) == -1) {
perror("close");
exit(EXIT_FAILURE);
}
return 0;
}
ssize_t write(int fd, const void * but, size_t count);
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
int main() {
int fd;
ssize_t bytes_written;
const char *data = "Hello, world!\n";
// 파일 열기
fd = open("output.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (fd == -1) {
perror("open");
exit(EXIT_FAILURE);
}
// 파일에 데이터 쓰기
bytes_written = write(fd, data, strlen(data));
if (bytes_written == -1) {
perror("write");
exit(EXIT_FAILURE);
}
// 파일 닫기
if (close(fd) == -1) {
perror("close");
exit(EXIT_FAILURE);
}
return 0;
}