4-3 File IO - 시스템 함수 (과제-1)
File Descriptor
- 시스템으로부터 할당 받은 파일을 대표하는 정수
- 파일을 관리하기 위해 시스템이 필요로 하는 파일에 대한 정보를 가지고 있는 제어블록 입니다.
- 파일마다 독립적으로 존재하며, 시스템에 따라 다른 구조를 가질 수 있씁니다.
- 대개 보조기억장치에 저장되어 있다가 해당 파일이 Open될 때 주기억장치로 이동합니다.
- 프로세스가 파일을 다룰 때 사용하는 개념으로, 프로세스에서 특정 파일에 접근할 때 사용하는 추상적인 값입니다.
- 일반적으로 음이 아닌 정수를 갖습니다.
- REG파일, DIR, 소켓, 파이프, 블록 디바이스, 캐릭터 디바이스 등 모든 객체들을 파일로 관리하는데, 프로세스가 이 파일들에 접근할 때
파일 디스크립터
를 이용합니다.- 프로세스가 실행 중에 파일을 Open하면, 커널은 해당 프로세스의 파일 디스크립터 숫자 중 사용하지 않는 가장 작은 값을 할당해줍니다.
- 그 다음 프로세스가 열려있는 파일에 시스템 콜을 이용해서 접근할 때, 파일 디스크립터(fd)값을 이용해서 파일을 지칭할 수 있습니다.
- 기본적으로 할당되는 fd는 표준입력(0), 표준출력(1), 표준에러(2) 입니다.
바이너리 파일 vs 텍스트 파일
- 바이너리 파일
- 데이터로 구성된 파일
- 모든 파일은 0과 1로 이루어져 있습니다.
- 파일 구성 형식에 특별한 조건이 없어서 대부분 데이터의 크기로 판단합니다.
- 데이터파일(.dat), 실행파일(.exe), 이미지파일(.png), 바이너리파일(.bin) 등
- 텍스트 파일
- 문자로 구성된 파일
- 대부분 ASCII문자나 문장들로 이루어져 있습니다.
- 소스코드파일(.cpp), README.txt 등
open()
함수 원형.
int open(const char* path, int flags)
int open(const char* path, int flags, mode_t mode)
기능. 이미 존재하는 파일을 열거나, 새로운 파일을 생성하는 함수
헤더.<sys/types.h> <sys/stat.h> <fcntl.h>
매개변수1.const char* path
대상 파일 이름
매개변수2.int flags
파일에 대한 열기 옵션
매개변수3.mode_t mode
O_CREAT 옵션 사용에 의해 파일이 생성될 때, 지정되는 파일 접근 권한 (예:0644, 0777)
리턴.
(성공) 파일 열기에 성공하면, 파일 디스크립터의 양의 정수값 반환
(실패) -1 errno
열기 옵션 | 옵션 설명 |
---|---|
O_RDONLY | 읽기 전용으로 열기 |
O_WRONLY | 쓰기 전용으로 열기 |
O_RDWR | 읽기와 쓰기 모두 가능 |
O_CREAT | 해당 파일이 없으면 생성 |
O_EXCL | 해당 파일이 존재하면 오류 발생 및 파일을 열지 않는다 |
O_TRUNC | 해당 파일이 존재하면 해당 파일의 모든 내용을 지운다 |
O_APPEND | 쓰기 동작 시 파일의 끝에 내용 추가 |
O_NOCTY | 열기 대상이 터미널일 경우, 이 터미널이 프로그램의 제어 터미널로 할당하지 않는다 |
O_NONBLOCK | 읽을 내용이 없을 때에는 읽을 내용이 있을 때까지 기다리지 않고 바로 복귀한다 |
O_SYNC | 쓰기 동작 시 물리적인 쓰기 동작이 완료될 때까지 대기 |
read()
함수 원형.
ssize_t read(int fd, void* buf, size_t nbytes)
기능. open() 함수로 열기한 파일의 내용을 읽습니다
nbytes가 제로면 error
nbytes가 SSIZE_MAX보다 크면, implementation-defined
헤더. <unistd.h>
매개변수1.int fd
읽을 파일의 파일 디스크립터
매개변수2.void* buf
읽어들인 데이터를 저장할 버퍼
매개변수3.size_t nbytes
읽어들일 데이터의 최대 길이 (buf의 길이보다 길어선 안됨)
리턴.
(성공) 읽어들인 데이터 길이(바이트 수)
무조건 nbytes가 리턴되는건 아님. 중간에 파일의 끝을 만난다면 거기까지 읽기 때문.
(실패) -1 errno
write()
함수 원형.
ssize_t write(int fd, const void* buf, size_t nbytes
)
기능. 파일의 내용을 작성합니다
헤더. <unistd.h>
매개변수1.int fd
open(), creat() 등을 통하여 정상적으로 open한 파일 디스크립터
매개변수2.const void* buf
쓰기를 할 데이터 메모리 영역
매개변수3.size_t nbytes
쓸 데이터의 사이즈
리턴.
(성공) 실제로 쓴 데이터의 byte 수 (0보다 큰 값)
count와 같은 크기의 값을 return하지만,
count보다 작은 경우에는 signal이 발생하였거나, 쓰기 공간이 부족한 경우
(0) 오류가 발생하지는 않았지만, 파일에 write되지 않음(count가 0인 경우)
(실패) -1 errno
lseek()
함수 원형.
off_t lseek(int fd, off_t offset, int whence)
기능. file의 특정 위치부터 읽거나 쓰고싶을 때 유용합니다.
파일을 처음 열면 최초의 seek position은 0입니다.
open()에서 O_APPEND 플래그를 주면, 최초의 seek position은 파일의 끝에 있습니다.
헤더. <sys/types.h> <unistd.h>
매개변수1.int fd
조정할 파일의 파일 디스크립터
매개변수2.off_t offset
기준점으로부터 이동할 거리
매개변수3.int whence
기준점
SEEK_SET(0) : 파일의 시작
SEEK_CUR(1) : 현재 Seek 포인터
SEEK_END(2) : 파일의 끝
리턴.
(성공) 성공 시 위치한 Seek pointer 위치
(실패) -1 errnolseek(fd, 10, SEEK_SET); //파일의 시작에서 10번을 건너뛴다. lseek(fd, -8, SEEK_END); //파일의 끝에서 앞으로 8번을 건너뛴다. lseek(fd, 5, SEEK_CUR); //현재 위치에서 다시 5번을 건너뛴다.
close()
함수 원형.
int close(int fd)
기능. open() 함수로 열기한 파일을 사용 중지합니다.
헤더. <unistd.h>
매개변수.int fd
파일 디스크립터
리턴.
(성공) 0 정상적으로 close
(실패) -1
과제 - 1
my_cp 파일 복사
#include <stdio.h>
#include <errno.h>
#include <sys/types.h> //open()
#include <sys/stat.h> //open()
#include <fcntl.h> //open()
#include <unistd.h> //read() write() close()
#include <string.h> //strcmp()
enum { BUF_SIZE = 300 };
void Usage()
{
printf("Usage: c [-f] src_file dest_file\n");
printf(" -f: dest_file 존재시 src_file 내용으로 바꿈\n");
}
int main(int argc, char* argv[])
{
if (argc != 3 && argc != 4) {
Usage();
return EIO;
}
if (argc == 4 && (strcmp(argv[1], "-f") != 0)) {
Usage();
return EIO;
}
int src = 0;
int dest = 0;
char buf[BUF_SIZE];
int f = 0;
if (strcmp(argv[1], "-f") == 0) {
f = 1;
}
if ((src = open(argv[1 + f], O_RDWR)) == -1) {
printf("No such file\n");
return ENOENT;
}
if (f == 0) {
if ((dest = open(argv[2 + f], O_RDWR | O_CREAT | O_EXCL, 0777)) == -1) {
printf("Copy fail (%s existed)\n", argv[2 + f]);
return EEXIST;
}
}
else if (f == 1) {
if ((dest = open(argv[2 + f], O_RDWR | O_CREAT | O_TRUNC, 0777)) == -1) {
printf("Copy fail (can't access)\n");
return EACCES;
}
}
if (read(src, buf, BUF_SIZE - 1) == -1) {
return EFAULT;
}
if (write(dest, buf, strlen(buf) - 1) == -1) {
return EFAULT;
}
else {
printf("Copy success!!!\n");
}
if (close(src) == -1) {
return EBADF;
}
if (close(dest) == -1) {
return EBADF;
}
return 0;
}
Author And Source
이 문제에 관하여(4-3 File IO - 시스템 함수 (과제-1)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@doheeklm/4-3저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)