[Linux] 파일 시스템의 기본 다루기: open, close, read, write

Ma_Seokjae·2024년 3월 27일
0
post-thumbnail

운영체제 과제를 하면서 다루었던 파일 시스템을 운용하는 주요 함수들과 구조체에 대해서 간단하게 정리해보려고 합니다

1. open 함수

open 함수는 파일을 열거나 생성하기 위해 사용됩니다

  • int open(const char *pathname, int flags, mode_t mode);
  • 파라미터 정보:
    • pathname: 열고 싶은 파일의 경로
    • flags: 파일을 여는 방법을 지정하는 정보
    • mode: 새 파일을 생성할 때 파일 권한 설정
  • 반환 값:
    • 성공 시: *파일 디스크립터
    • 실패 시: -1

flag 정보:

  • O_RDONLY: 읽기 전용으로 열기
  • O_WRONLY: 쓰기 전용으로 열기
  • O_RDWR: 읽기와 쓰기 모두 가능하게 열기
  • O_CREAT: 파일이 존재하지 않을 경우 새로 생성
  • O_EXCL: O_CREAT와 함께 사용되며, 파일이 이미 존재하면 에러 반환
  • O_TRUNC: 파일을 열 때, 파일의 길이를 0으로 설정
  • O_APPEND: 쓰기 작업 시, 파일 끝에 추가

예시:

int fd = open("example.txt", O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
if (fd == -1) {
    perror("open");
    return 1;
}

2. close 함수

close 함수는 열린 파일 디스크립터를 닫습니다

  • int close(int fd);
  • 파라미터 정보:
    • fd: 닫으려고 하는 파일의 파일 디스크립터
  • 반환 값:
    • 성공 시, 0
    • 실패 시, -1

예시:

if (close(fd) == -1) {
    perror("close");
    return 1;
}

3. read 함수

read 함수는 파일에서 데이터를 읽습니다

  • ssize_t read(int fd, void *buf, size_t count);
  • 파라미터 정보:
    • fd: 데이터를 읽을 파일의 파일 디스크립터
    • buf: 읽은 데이터를 저장할 버퍼의 주소
    • count: 최대로 읽을 바이트 수
  • 반환 값:
    • 실제로 읽은 바이트 수 OR 파일 끝(EOF)에 도달 시, 0
    • 실패 시, -1

예시:

char buffer[1024];
ssize_t bytes_read = read(fd, buffer, sizeof(buffer));
if (bytes_read == -1) {
    perror("read");
    return 1;
}

4. write 함수

write 함수는 파일에 데이터를 씁니다

  • ssize_t write(int fd, const void *buf, size_t count);
  • 파라미터 정보:
    • fd: 데이터를 읽을 파일의 파일 디스크립터
    • buf: 쓸 데이터를 가지고 있는 버퍼의 주소
    • count: 쓸 바이트 수
  • 반환 값:
    • 실제로 쓴 바이트 수
    • 실패 시, -1

예시:

const char *str = "Hello, world!";
ssize_t bytes_written = write(fd, str, strlen(str));
if (bytes_written == -1) {
    perror("write");
    return 1;
}

이 네 가지 함수들을 사용해서 파일 처리, 데이터 읽기 및 쓰기와 같은 기본적인 파일 시스템 작업을 수행합니다


궁금한 점?

Q. 파일 디스크립터가 뭔가요?

A: 파일 디스크립터(File Descriptor)는 운영 체제가 프로세스에서 파일이나 다른 입출력 리소스(예: 파이프, 네트워크 연결)에 접근할 수 있도록 제공하는 추상화된 핸들입니다.

운영 체제는 파일 디스크립터를 사용하여 프로세스와 파일 시스템 간의 인터페이스를 관리합니다. 프로그램이 파일을 열 때, 운영 체제는 해당 파일에 대한 접근 권한을 검사하고, 접근이 허용되면 내부적으로 파일에 대한 참조를 생성하고 해당 참조에 대응하는 파일 디스크립터를 프로그램에게 반환합니다.

리눅스와 유닉스 계열 운영 체제에서는 기본적으로 세 가지 파일 디스크립터가 자동으로 할당됩니다:

  • 0: 표준 입력(Standard Input, stdin)
  • 1: 표준 출력(Standard Output, stdout)
  • 2: 표준 오류(Standard Error, stderr)

이러한 방식으로 파일 디스크립터는 프로그램이 시스템의 입출력 리소스에 접근하고 조작하는 데 필수적인 역할을 합니다. 파일 디스크립터를 통해 운영 체제는 프로세스가 리소스를 효율적으로 관리할 수 있도록 지원합니다.

Q. open, close, read, write 함수들과 fopen, fclose, fread, fwrite와 같이 f로 시작하는 함수들 차이는 뭔가요?

A: 주요 차이는 운영 체제 수준의 시스템 호출과 라이브러리 레벨의 추상화 간의 차이에 있습니다.

시스템 호출 함수 (open, close, read, write)

  • 이 함수들은 운영 체제의 시스템 호출을 직접적으로 사용
  • 파일을 다룰 때 파일 디스크립터(정수 값)를 사용하여 파일을 참조
  • 더 낮은 수준의 파일 조작을 제공하며, 세밀한 제어가 가능
  • 리눅스, 유닉스와 같은 POSIX 호환 운영 체제에서 주로 사용
  • 버퍼링이 없기 때문에, 입출력 성능에 직접적인 영향을 줌

표준 입출력 라이브러리 함수 (fopen, fclose, fread, fwrite)

  • 이 함수들은 C 표준 라이브러리에 정의된 함수들로, 보다 고수준의 입출력 작업을 위한 추상화를 제공
  • 파일을 다룰 때 FILE * 구조체 포인터를 사용하여 파일을 참조
  • 사용이 더 쉽고, 플랫폼 독립적인 코드 작성이 가능
  • 내부적으로 버퍼링을 지원하여 입출력 성능을 개선
  • 파일 열기, 읽기, 쓰기, 닫기 등의 작업을 좀 더 추상화된 방식으로 다룸

정리하자면, 표준 입출력 라이브러리 함수들은 일반적으로 포터블 코드를 작성하는 데 있어 선호되며, 시스템 호출 함수들은 더 낮은 수준의 제어가 필요한 경우에 사용됩니다.

profile
Why not change the code?

0개의 댓글

관련 채용 정보