System programming - file
지금까지는 background에 대해서 공부했다. 이제부터 본격적인 시스템 프로그래밍을 다룬다.
File system calls - open, read, write
open - 파일을 처음 열 때
read - 파일로부터 데이터를 읽을 때
write - 우리가 원하는 데이터를 파일에다가 쓸 때
open은 x = open("/aa/bb", O_RDWR, 00777); 이런식의 구조로 사용한다.
"/aa/bb"는 주소를 주는 장소이기 때문에 string 상수로 주어도되고 array의 이름(포인터 변수)으로 주어도 된다.
O_RDWR은 종류가 많다. 종류는 다음과 같다.
O_RDONLY : open for read only 읽기 전용
O_WRONLY : open for write only 쓰기 전용
O_RDWR : open for read and write 둘다 전용
O_RDWR | O_CREAT: open for read and write. create if not exist 파일을 열 때 파일이 없으면 만들어라.
O_RDWR | O_CREAT | O_TRUNC : open for read and write. create if not exist. empty it before writing. 파일을 오픈할 때 파일에 데이터가 있으면 그 데이터를 모두 지운다.
햇갈리지만 잘 읽어보면 모두 영어단어의 조합이다. 가장 많이 보이는 것은 RD, WR, ONLY정도라고 보면 될 것 같다.
마지막의 00777은 무엇일까? 이건 그냥 이렇게 써주면 된다. 그냥 기본 모드.
open의 return 값은 file에 대한 번호가 리턴된다. (오픈에 성공했을 때) 따라서 print로 x를 찍으면 시스템이 부여한 파일의 번호를 볼 수 있다. (이 때 프로그램에서만 사용할 수 있는 번호이다.)만약 실패했다면 그때는 -1이 return된다.
파일 번호는 보통 3번부터 번호가 부여된다. 예를 들어 처음 오픈을 하면 3번 그 다음은 4번이 되는 것이다. 그렇다면 0, 1, 2번은 무엇일까? 바로 표준파일이다. 0번은 standard input file, 1번은 standard output file, 2번은 standard error file. 보통 0번 파일은 키보드를 의미하고 1, 2번 파일은 화면을 의미한다.
open하고 파일 이름을 지정할 때 Absolute 혹은 Relative path를 줄 수 있다. 첫번째 글자가 /로 시작하면 절대 경로, 아니라면 상대 경로이다. 앞서 포스팅했던 절대, 상대 경로의 설명대로 파일을 찾게된다.
이제 read 함수를 살펴보자.read는 y = read(x, buf, 10); 로 사용된다.여기서 x는 open했을 때 return된 파일 번호이다. read를 할 때는 먼저 open을 해서 파일 번호를 받은 다음에 읽는다. 그렇기 때문에 첫번째 매개변수는 데이터를 읽을려는 파일 번호를 준다.
그 다음인 buf는 그 데이터를 받아서 저장할 위치. 즉 char array이다.
그 다음은 최대 몇 byte를 읽은 것인지 적는 것이다.
정리하면 y는 x라는 파일을 받아서 최대 10 byte를 받아서 buf에 저장하는 것이다.
read는 실제 읽은 byte 수를 return하도록 되어있다. 10byte를 읽었으면 10, 파일이 5byte밖에 없었으면 5, 파일을 끝까지 읽은 상태에서 한번 더 읽으라고 하면 0이 리턴된다. (read는 read를 실행할 때마다 그 다음 위치에서 계속 읽는다. 그렇기 때문에 0이 되는 것) 즉, read가 0을 리턴한다면 파일을 다 읽었다고 보면된다. 오류가 발생하면 -1이 return된다.
buf[y]는 그럼 무엇이 되겠는가? 바로 string이 되는 것이다. (혹은 char의 array)read를 쓸 때는 보통 루프를 쓴다. 0이 리턴이 될 때까지 계속 읽는 식으로 코딩한다.
마지막으로 write이다.write은 y = write(x, buf, 10); 으로 쓴다. read와 거의 비슷하지만 뜻은 x라는 파일에다가 데이터를 쓰라는 뜻이고 그 데이터는 buf가 가리키는 char array를 쓰라는 것이다. 여기서 10은 최대 10byte까지 적으라는 뜻이다.buf는 다시 한번 말하지만 주소이다. 그렇기 때문에 직접 "hello"와 같이 스트링상수를 그냥 넣어도 된다. return은 실제 쓴 byte 수를 return 한다.
Standard input, output, error file을 알아보자.
y = read(0, buf, 4); 라고 하면 파일 0번을 주면 이는 키보드에 입력하라는 것이다. 즉, scanf와 비슷하다고 보면된다.
y = write(1, buf, 10); 이라면 파일 1번은 화면에다가 쓰라는 뜻이다. 즉, printf대신에 쓸 수도 있다는 뜻이다.
y = write(2, buf, 10); 이것은 파일 2번으로 에러 파일인데 이것도 마찬가지로 화면에다가 쓴다.
open, read, write는 header파일이 많이 필요하다.