시스템 프로그래밍 3일차
유튜브 강의 참고
File read & write
read
$ man -s 2 read
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
fd (file descriptor)
buf (buffer)
count
Return
- 0: 파일의 끝(EOF)에 도달, -1: 에러
write
$ man -s 2 write
#include <unistd.h>
# const 수정이 불가
ssize_t write(int fd, const void *buf, size_t count);
fd (file descriptor)
buf (buffer)
- 기록할 내용이 저장된 buffer의 시작 주소
count
return: 실제로 기록한 byte 수
File offset
- File operation (read/write)를 적용할 위치
- 파일의 시작점부터 현재 위치까지의 byte 수
- Read(2)/write(2) 수행 시, 읽은/기록한 byte 수 만큼 순차적으로 이동
read write 실습
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
int main(void) {
int rfd, wfd, n;
char buf[10];
rfd = open("hello.txt", O_RDONLY);
if(rfd == -1) {
perror("Open hello.txt");
exit(1);
}
wfd = open("hello.bak", O_CREAT | O_WRONLY | O_TRUNC, 0644);
if (wfd == -1) {
perror("Open hello.bak");
exit(1);
}
while ((n = read(rfd, buf, 6)) > 0){
if (write(wfd, buf, n) != n) perror("Write");
printf("%d", n);
}
if (n == -1) perror("Read");
close(rfd);
close(wfd);
return 0;
}
# hello.txt 생성
root@test-ubuntu:~/test/2-3# echo "Hello system programming" > hello.txt
# hello.bak 파일 없는거 확인
root@test-ubuntu:~/test/2-3# cat hello.bak
cat: hello.bak: No such file or directory
# 실행파일 실행
root@test-ubuntu:~/test/2-3# ./read_write.out
# hello.txt 가 백업 된 것을 확인
root@test-ubuntu:~/test/2-3# cat hello.bak
Hello system programming
File access methods
순차 접근 (Sequential access)
- File을 record(or bytes) 단위로 순서대로 접근
- fgetc()
직접 접근 (Directed access)
- 원하는 Block를 직접 접근
- lseek(), seek()
lseek (직접 접근)
#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);
fd (file descriptor)
- 대상 file descriptoroffset
- 이동시킬 byte 수 (양수 or 음수)whence
- 기준 위치Return: 이동후 file offset
- -1: 에러
whence
- SEEK_SET: 파일 시작
- SEEK_CUR: 현재 위치
- SEEK_END: 파일의 끝
사용 예
lseek(fd, 5, SEEK_SET);
- 파일 시작에서 5번째 byte로 이동
- lseek(fd, 0, SEEK_END);
- 파일 끝으로 이동
- cur_offset = lseek(fd, 0, SEEK_CUR);
- 내 현재 위치
file offset 실습
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
int main(void) {
int fd, n;
off_t start, cur;
char buf[256];
fd = open("linux.txt", O_RDONLY);
if (fd == -1) {
perror("Open linux.txt");
exit(1);
}
start = lseek(fd, 0, SEEK_CUR); // 현재 위치 저장
n = read(fd, buf, 255); // 0 byte에서 255 byte 까지 저장
buf[n] = '\0'; // `\0`는 문자열 마지막 의미
printf("offset start=%d, Read Str=%s, n=%d\n", (int)start, buf, n); // 현재 위치 start 출력, Str 출력, 남은 byte수 출력
cur = lseek(fd, 0, SEEK_CUR);
printf("offset cur=%d\n", (int)cur);
start = lseek(fd, 6, SEEK_SET); // 6번째 byte로 이동
n = read(fd, buf, 255); // 6번째 byte에서 255 바이트까지 읽기
buf[n] = '\0'; // `\0`는 문자열 마지막 의미
printf("Offset start=%d, Read Str=%s", (int)start, buf); // 현재 위치 start 출력, Str 출력, 남은 byte수 출력
close(fd);
return 0;
}
# linux.txt 생성
root@test-ubuntu:~/test/2-3_seek# echo "Linux System Programming" > linux.txt
# 실행파일 실행
root@test-ubuntu:~/test/2-3_seek# ./seek.out
# 출력
offset start=0, Read Str=Linux System Programming
, n=25
offset cur=25
Offset start=6, Read Str=System Programming
Page cache & write-Back
Page cache
- In-memory store of recently accessed data from an on-disk filesystem
- disk 접근 시간 절약을 위해 kernel 내부적 기법
Page write-back
- Page cache에 변경 된 내용을 disk에 반영하는 것
- 반영 시기는 kernel이 결정
fsync
#include <unistd.h>
int fsync(int fd);
Page write-back을 강제로 수행
fd (file descriptor)
- fd (file descriptor)
Return
- 0: success
- -1: error