반응형
read(2)
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
open(2), creat(2), socket(2), accept(2) 등으로 생성한 file descriptor로 부터 데이터를 읽습니다. 파일을 읽으면 읽은 size만큼 파일의 다음 읽을 위치가 이동됩니다. 읽을 위치가 파일의 끝에 도달하면 더 이상 읽을 데이터가 없으므로 0을 return합니다.
파라미터
fd
- open(2), creat(2), socket(2), accept(2) 등을 통하여 정상적으로 open한 file descriptor
buf
- 읽을 데이터를 저장할 메모리 영역(buffer)
count
- 읽을 size (byte 수)
RETURN
0보다 큰 수
- 실제로 읽은 데이터 byte 수.
- 일반적으로 count와 같은 값을 return하지만, count보다 작은 경우에는 end of file에 도달하였거나,
socket통신에서는 수신할 데이터가 아직 도착하지 않은 경우나
peer(상대)에서 socket을 close했을 때입니다.
0
- end of file에 도달하여 더 이상 읽을 자료가 없는 경우
-1
- 오류가 발생한 경우이며 상세한 오류는 errno에 설정됩니다.
EAGAIN : file을 open할 때에 O_NONBLOCK flag이 설정되었으며,
현재 읽을 데이터가 없어서 read()함수를 바로 return함.
EAGAIN or EWOULDBLOCK : fd가 socket이고 socket에 O_NONBLOCK으로 설정된 경우
읽을 데이터를 수신하지 못하여 바로 return함.
EBADF : fd가 유효하지 않은 file descriptor임.
EFAULT : buf가 access할 수 없는 영역의 데이터 buffer임.
주로 변수를 pointer로 설정한 후에 malloc(3)하지 않은 경우
EINTR : signal이 발생하여 interrupt됨.
EINVAL : fd, buf, count 등의 변수가 잘못 설정된 경우. (예, count가 -값이 설정된 경우 등)
EIO : I/O 오류. background process에서 terminal에 대한 I/O를 시도했다든 지...
EISDIR : open된 fd가 directory인 경우
활용 예제
Sample. 파일 backup
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
/*
* 읽을 데이터를 요청한 사이즈 만큼 읽어들임.
* 파일의 끝이면 요청한 사이즈보다 작을 수 있음.
* Signal이 발생하더라도 읽기를 처리함.
*/
int read_data(int fd, char *buffer, int buf_size)
{
int size = 0;
int len;
while(1) {
if((len = read(fd, &buffer[size], buf_size - size)) > 0) {
size += len;
if(size == buf_size) {
return size;
}
} else if(len == 0) {
return size;
} else {
if(errno == EINTR) {
continue;
} else {
return -1;
}
}
}
}
/*
* 저장할 데이터를 요청한 사이즈 만큼 write함
* signal이 발생하더라도 저장함
*/
int write_data(int fd, const char *buffer, int buf_size)
{
int size = 0;
int len;
while(1) {
if((len = write(fd, &buffer[size], buf_size - size)) > 0) {
size += len;
if(size == buf_size) {
return size;
}
} else if(len == 0) {
return size;
} else {
if(errno == EINTR) {
continue;
} else {
return -1;
}
}
}
}
int main(int argc, char *argv[])
{
int rfd;
int wfd;
int len;
char buffer[4096];
/* 파일을 읽기 전용으로 open함 */
if((rfd = open("sample.txt", O_RDONLY)) == -1) {
fprintf(stderr, "FILE READ OPEN ERROR: %s\n", strerror(errno));
return 1;
}
/* 쓰기 전용으로, 파일이 없으면 생성하고, 파일이 있으면 전체데이터를 삭제하고 open함 */
if((wfd = open("sample.txt.bak", O_WRONLY | O_CREAT | O_TRUNC, 0644)) == -1) {
fprintf(stderr, "FILE WRITE OPEN ERROR: %s\n", strerror(errno));
return 1;
}
while(1) {
if((len = read_data(rfd, buffer, 4096)) == -1) {
fprintf(stderr, "READ ERROR: %s\n", strerror(errno));
return 1;
}
if(len == 0) {
break;
}
if((len = write_data(wfd, buffer, len)) == -1) {
fprintf(stderr, "WRITE ERROR: %s\n", strerror(errno));
return 1;
}
}
close(rfd);
close(wfd);
return 0;
}
see also: System Call File I/O Library
반응형
'C언어 header > unistd.h' 카테고리의 다른 글
rmdir(2) - directory 삭제하기 (0) | 2019.10.04 |
---|---|
write(2) - 파일에 데이터 쓰기 (0) | 2019.10.04 |
usleep(3) - 설정된 micro초(microsecond: 100만분의 1초) 동안 대기 (0) | 2019.10.01 |
unlink(2) - 파일 삭제 (1) | 2019.10.01 |
truncate(2) - 파일의 크기를 조정하기 (0) | 2019.10.01 |