#include <unistd.h>
ssize_t read (int fd, void *but,size_t count);
디스크의 카운트 만큼 읽어서 메모리의 버퍼만큼 저장
실제로 몇개를 읽었느냐?
#include <unistd.h>
ssize_t write (int fd, const void *buf , size_t count);
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
int main(void){
int rfd, wfd, n;
char buf[10]={0};
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 hellow.bak");
exit(1)
}
==> hello라는 프로그램을 hello.bak으로 복사
...
while ((n=read(rfd,buf,6))>0)
if(write(wfd,buf,n)!=n) perror("Write")
if(n==-1) perror("Read");
close(rfd)
close(wfd);
return 0;
}
read를 보면 리드파일 디스크립터, 버퍼공간(10칸),
파일 안에 있는 6개를 읽어서 버퍼로 가지고옴
이 파일은 hello.txt 파일
오프셋은 0번부터 6번까지
여기서 hello.bak 를 wfd가 가리킴
버퍼에 있는 것을 n개 쓴다. n은 뭐냐?
read가 실제로 읽은 바이트의 수
== read 시스템콜이 읽은 만큼 쓰겠다
파일안에 글자가 몇개 있는지 모른다.
글자의 수를 모르기 때문에 while로 반복한다.
직접 실행해보자.
코드:
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
int main(void){
int rfd, wfd, n;
char buf[1024]={0};
rfd = open("a.txt", O_RDONLY);
if(rfd == -1){
perror("Open a.txt");
exit(1);
}
wfd = open("result.txt", O_CREAT|O_WRONLY|O_TRUNC, 0666);
if(wfd == -1){
perror("Open result.txt");
exit(1);
}
while((n=read(rfd,buf,6))>0)
if(write(wfd,buf,n)!=n) perror("Write");
if(n==-1) perror("Read");
close(rfd);
close(wfd);
return 0;
}
권한을 0644로 하면 Permission Denied가 발생한다.
다른 코드:
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#define BUFFER_SIZE 1024
int main(int argc, char *argv[]) {
int fd1, fd2, n;
char buf[BUFFER_SIZE];
// 명령행 인자 개수 확인
if(argc != 3) {
printf("Usage: %s <source> <destination>\n", argv[0]);
exit(EXIT_FAILURE);
}
// 소스 파일 열기
if((fd1 = open(argv[1], O_RDONLY)) == -1) {
perror(argv[1]);
exit(EXIT_FAILURE);
}
// 대상 파일 열기
if((fd2 = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0644)) == -1) {
perror(argv[2]);
exit(EXIT_FAILURE);
}
// 소스 파일에서 데이터 읽어들이고 대상 파일에 쓰기
while((n = read(fd1, buf, BUFFER_SIZE)) > 0) {
if(write(fd2, buf, n) != n) { // 대상 파일에 쓰기
perror(argv[2]);
exit(EXIT_FAILURE);
}
}
// read() 함수에서 오류 발생 시 처리
if(n == -1) {
perror(argv[1]);
exit(EXIT_FAILURE);
}
// 파일 닫기
if(close(fd1) == -1 || close(fd2) == -1) {
perror("close");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
두 코드의 차이점
실행 파일의 권한은 실행 권한에 대해서만 적용되기 때문에, 두 번째 코드는 실행 파일의 권한이 0666이 아니더라도 권한 거부가 일어나지 않습니다. 즉, 파일의 읽기/쓰기 권한은 실행 파일의 권한과 상관 없이 파일 자체의 권한 설정에 따라 결정됩니다. 첫 번째 코드에서 대상 파일의 권한은 O_CREAT 옵션에 의해 생성되기 때문에, 생성된 파일의 권한은 0644로 설정됩니다.
순차접근 : file을 record 단위로 순서대로 접근
직접접근 : 원하는 블럭을 직접 접근
#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fd, off, int whence);
어디서부터(whence) 얼마나(offset)
whence
사용 예
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
int main(){
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);
buf[n] = '\n'; // 문자열의 끝
printf("Offset start=%d, Read Str=%s, n=%d\n", (int)start, buf, n); // 시작점, 읽은 내용, 몇개나 읽었는지
cur = lseek(fd,0,SEEK_CUR); // 현재 위치
printf("Offset cur=%d\n",(int)cur);
start = lseek(fd,6,SEEK_SET); // 처음부터 6칸
n= read(fd,buf,255); //기존의 버퍼내용은 씌움
buf[n] = '\n';
printf("Offset start=%d, Read Str=%s,(int)start, buf);
close(fd);
return 0;
}
코드 작성해보기
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#define BUFFER_SIZE 1024
int main(void){
int rfd, wfd, n;
char buf[BUFFER_SIZE] = {0};
rfd = open("test.txt", O_RDONLY);
if(rfd == -1){
perror("Open test.txt");
exit(1);
}
wfd = open("result.txt", O_CREAT|O_WRONLY|O_TRUNC, 0666);
if(wfd == -1){
perror("Open result.txt");
exit(1);
}
lseek(rfd, 23, SEEK_SET); // 문자열 "It is by standing"까지 이동
while((n=read(rfd,buf,BUFFER_SIZE))>0){
if(write(wfd,buf,n)!=n) perror("Write");
}
if(n==-1) perror("Read");
close(rfd);
close(wfd);
return 0;
}
실행 결과
페이지 캐시
디스크 접근 시간 절약을 위해 커널 내부적 기법
page write-back
#include <unistd.h>
int fsync(int fd);