리눅스의 File Descriptor, 윈도우의 File Handle

아트·2024년 10월 19일

Computer Science

목록 보기
13/14

파일 디스크립터 (File Descriptor)

파일 디스크립터(File Descriptor)는 운영체제에서 파일을 다룰 때 사용하는 추상적인 개념입니다. 주로 유닉스 계열의 운영체제(리눅스, macOS 등)에서 사용되며, 파일, 소켓, 파이프 등의 자원을 관리하고 접근하는 데 사용됩니다.

파일 디스크립터의 주요 특징

  1. 정수 값으로 표현: 파일 디스크립터는 각 프로세스 내에서 고유한 정수 값으로 표현됩니다. 즉, 파일 디스크립터는 파일이나 소켓 같은 자원을 열 때 할당되는 숫자입니다.

    • 일반적으로 파일 디스크립터는 0, 1, 2로 시작합니다:
      • 0: 표준 입력 (stdin)
      • 1: 표준 출력 (stdout)
      • 2: 표준 오류 출력 (stderr)
  2. 파일 입출력에 사용: 프로그램이 파일을 읽거나 쓰기 위해 파일을 열면 운영체제는 파일 디스크립터를 할당하고, 해당 디스크립터를 사용하여 파일에 접근합니다. 예를 들어, 파일에 데이터를 쓰려면 그 파일에 대응되는 파일 디스크립터를 통해 쓰기 작업을 수행합니다.

  3. 자원의 참조: 파일 디스크립터는 단순히 파일뿐 아니라 소켓, 파이프, 디바이스 등의 다양한 자원에 대한 참조를 제공합니다. 운영체제는 이 디스크립터를 사용해 파일뿐 아니라 네트워크 연결, 프로세스 간 통신, 디바이스 파일에 대한 작업을 처리합니다.

  4. 파일 디스크립터 제한: 각 프로세스마다 사용할 수 있는 파일 디스크립터의 수는 제한적입니다. 리눅스에서 ulimit 명령어를 통해 확인할 수 있으며, 너무 많은 파일을 동시에 열면 "Too many open files" 오류가 발생할 수 있습니다.

파일 디스크립터의 동작 예시 (리눅스)

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

int main() {
    int fd; // 파일 디스크립터
    char buffer[] = "Hello, world!\n";

    // 파일 열기
    fd = open("example.txt", O_WRONLY | O_CREAT, 0644);
    if (fd == -1) {
        perror("파일 열기 실패");
        return 1;
    }

    // 파일에 쓰기
    if (write(fd, buffer, sizeof(buffer)) == -1) {
        perror("파일 쓰기 실패");
        close(fd);
        return 1;
    }

    // 파일 닫기
    close(fd);
    return 0;
}

이 코드에서는 open 함수로 파일을 열고, 파일 디스크립터가 할당된 후 write 함수를 사용해 데이터를 쓰며, 작업이 완료되면 close 함수를 사용해 파일 디스크립터를 닫습니다.

윈도우의 파일 핸들 (File Handle)

윈도우에서도 유사한 개념으로 파일 핸들(File Handle)이 사용됩니다. 파일 핸들은 운영체제가 파일, 소켓, 파이프 등의 자원에 접근할 수 있도록 관리하는 식별자입니다.

윈도우의 파일 핸들 특징

  1. 핸들은 정수 또는 포인터: 윈도우의 파일 핸들은 정수 값이 아닌 포인터 또는 정수 형태의 값으로 운영체제가 자원을 식별하는 데 사용됩니다.

  2. 파일 입출력 API: 윈도우에서 파일 핸들을 사용하는 주요 함수들은 CreateFile(), ReadFile(), WriteFile(), CloseHandle() 등이 있습니다.

    • CreateFile() 함수는 파일을 열거나 생성하고, 파일 핸들을 반환합니다.
    • ReadFile()WriteFile() 함수는 파일 핸들을 사용해 파일의 내용을 읽거나 씁니다.
    • CloseHandle() 함수는 사용한 파일 핸들을 닫아 자원을 해제합니다.
  3. 핸들의 범용성: 파일 핸들은 파일뿐 아니라 네트워크 소켓, 이벤트, 프로세스, 스레드 같은 자원에도 사용됩니다.

  4. 핸들 제한: 프로세스가 열 수 있는 핸들의 수는 제한적입니다. 특정 자원을 너무 많이 열면 핸들 누수가 발생할 수 있으며, 이를 방지하려면 자원이 사용된 후 반드시 핸들을 닫아야 합니다.

윈도우 파일 핸들 사용 예시 (C/C++)

#include <windows.h>
#include <stdio.h>

int main() {
    HANDLE hFile;
    DWORD dwBytesWritten = 0;
    char buffer[] = "Hello, Windows!\n";

    // 파일 열기
    hFile = CreateFile("example.txt",              // 파일 이름
                       GENERIC_WRITE,              // 쓰기 권한
                       0,                          // 공유 모드 없음
                       NULL,                       // 기본 보안 속성
                       CREATE_NEW,                 // 파일이 없으면 새로 만듦
                       FILE_ATTRIBUTE_NORMAL,      // 일반 파일 속성
                       NULL);                      // 템플릿 파일 없음

    if (hFile == INVALID_HANDLE_VALUE) {
        printf("파일 열기 실패: %d\n", GetLastError());
        return 1;
    }

    // 파일 쓰기
    if (!WriteFile(hFile, buffer, sizeof(buffer), &dwBytesWritten, NULL)) {
        printf("파일 쓰기 실패: %d\n", GetLastError());
        CloseHandle(hFile);
        return 1;
    }

    // 파일 닫기
    CloseHandle(hFile);

    return 0;
}

요약

  • 파일 디스크립터는 유닉스 계열 운영체제에서 파일, 소켓, 파이프 등의 자원에 접근하기 위해 사용되는 추상적인 정수 식별자입니다.
  • 파일 핸들은 윈도우에서 사용되며, 포인터 또는 정수 값으로 파일, 소켓, 이벤트 같은 자원을 관리합니다.
  • 두 개념 모두 파일이나 네트워크 소켓 같은 자원에 접근하고, 관리하는 방식이 비슷하며, 프로세스마다 이러한 자원을 참조하고 작업을 수행하는 데 사용됩니다.

0개의 댓글