시스템 프로그래밍-파일 디스크립터와 파일 포인터

YuWan·2024년 6월 13일

linux

목록 보기
4/26

시스템 프로그래밍이란

  • 운영체제, 하드웨어와 상호작용을 프로그래밍 하는 것
  • 커널이 제공하는 기능을 직접 제공받으며 low-level에서 동작하는 프로그램을 작성하는 것
  • 커널이 제공하는 기능: 시스템 콜 주로 활용
  • 운영체제, 네트워크 파트에서 학습한 내용을 소스코드 레벨에서 관측
  • 타 프로그래밍 언어를 이용하더라도 공통적으로 사용될 시스템 프로그래밍 개념

vi, vim 편집기

  • vi 파일이름을 통해 파일 생성 가능

파일 디스크립터(File Descripter)

  • 프로세스는 운영체제로부터 파일을 할당받는다. 이걸 어떻게 구분할까?
  • 파일을 식별하기 위해 운영체제로부터 할당받은 정보
  • 입출력장치, 파이프, 소켓도 파일 디스크립터로 식별
  • 일반적으로 0 이상의 정수 형태
  • 프로세스가 파일을 열거나 생성할 때 운영체제는 해당 파일에 대한 파일 디스크립터 할당
  • 저수준에서 파일을 식별하는 정보
  • 고정된 파일 디스크립터 값(표준 입출력)
  • 0번: 표준 입력
  • 1번: 표준 출력
  • 2번: 표준 에러

파일 디스크립터 반환받기:파일 열기

int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);

O_RDONLY:읽기 전용으로 열기
O_WRONLY:쓰기 전용으로 열기
O_RDWR:읽기 쓰기 전용으로 열기
O_CREAT:파일이 없다면 생성하기(mode_t mode 필수)
O_TRUNC:기존 파일 내용 삭제
O_APPEND:파일의 끝 지점부터 쓰기 시작(추가하기)

Parameter

  • pathname:파일 경로, flag: 접근 플래그, mode: 파일 생성시 모드

리눅스의 권한 설정

  • 소유자(rwx), 그룹(rwx), other(rwx)
  • 일기 4, 쓰기 2, 실행 1 Owner, Group, Other

Return

  • 성공시 파일 디스크립터
  • 실패시 -1

파일 닫기

int close(int fd);

Parameter

  • fd:닫고자 하는 파일 디스크립터

Return

  • 성공시 0
  • 실패시 -1

open-close 예제 코드

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

int main() {
    int fd; //변수 선언

    // 파일을 열고 파일 디스크립터를 얻음
    fd = open("example.txt", O_RDONLY);

    if (fd == -1) {
        perror("Failed to open the file");
        return 1;
    }

    printf("File descriptor: %d\n", fd);

    // 파일을 닫음
    if (close(fd) == -1) {
        perror("Failed to close the file");
        return 1;
    }

    return 0;
}

자바의 파일 디스크립터

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileDescriptor;
import java.io.IOException;

public class File_2 {
    public static void main(String[] args) {
        try {
            String filePath = "example.txt";

            // 파일 디스크립터로 파일 열기
            FileInputStream fis = new FileInputStream(filePath);
            FileDescriptor fd = fis.getFD();

            // 파일 디스크립터 값 출력
            System.out.println("파일 디스크립터 값: " + fd.toString());

            // 파일 디스크립터를 이용한 파일 읽기
            byte[] buffer = new byte[1024];
            int bytesRead = fis.read(buffer);
            System.out.println("파일 내용: " + new String(buffer, 0, bytesRead));

            // 파일 닫기
            fis.close();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

파이썬의 파일 디스크립터

f_name = "example.txt"
fileObject = open(f_name, "r")

print("The file descriptor for %s is %s" % (f_name, fileObject.fileno()))

파일 포인터

  • (C 언어) FILE*타입
  • 파일을 스트림처럼 읽고 쓰기 위한 자료형->편리한 함수 기능 많음
  • 파일 디스크립터가 저수준에서 파일을 식별하는 저보라면 파일 포인터는 고수준 파일 식별 정보

파일 포인터로 파일 열기

FILE *fopen(const char *pathname, const char *mode);

Parameter

  • pathname: 파일경로
  • mode: 파일 열기 모드

Return

  • 성공시 파일 포인터
  • 실패시 NULL

파일 포인터로 파일 닫기

int fclose(FILE *stream);

Parameter

  • stream: 파일 포인터

Return

  • 성공시 0
  • 실패시 EOF

파일 포인터 예제

#include <stdio.h>

int main() {
    FILE *file; // 파일 포인터 선언

    // 파일 열기 시도
    file = fopen("example.txt", "w"); // "example.txt" 파일을 쓰기 모드로 열기

    if (file == NULL) {
        printf("파일을 열 수 없습니다.\n");
        return 1; // 오류 코드 반환
    }

    // 파일에 데이터 쓰기
    fprintf(file, "안녕하세요, 파일에 쓰는 예제입니다.\n");

    // 파일 닫기
    fclose(file);

    return 0; // 프로그램 종료
}

파일 디스크립터에서 파일 포인터 반환 받기

FILE *fopen(int fd, const char *mode);

Parameter

  • fd: 파일 디스크립터
  • mode: 권한

Return

  • 성공시 파일 포인터
  • 실패시 NULL

파일 포인터에서 파일 디스크립터 반환 받기

int fileno(FILE *stream);

Parameter

  • stream: 파일 포인터

Return

  • 성공시 파일 디스크립터
  • 실패시 -1

예제 코드

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

int main() {
    FILE *file; // 파일 포인터
    int fd;     // 파일 디스크립터

    // 파일 열기 시도
    file = fopen("example.txt", "r");
    if (file == NULL) {
        perror("파일 열기 오류");
        return 1;
    }

    // 파일 포인터를 파일 디스크립터로 변환
    fd = fileno(file);

    printf("file descriptor: %d\n", fd);

    // 파일 닫기
    fclose(file);

    return 0;
}
profile
공부 블로그

0개의 댓글