교재 : 리눅스 시스템 원리와 실제 (창병모, 생능출판)
12.1 파일 시스템
1) 파일 시스템 보기
- 명령어 : 파일 시스템에 대한 디스크 사용 정보를 보여준다.
$ df 파일시스템*
2) 디스크 사용량 보기
- 사용법 : 파일 혹은 디렉터리의 사용량을 보여준다. 파일을 명시하지 않으면 현재 디렉터리 내의 모든 파일들의 사용 공간을 보여준다.
$ du [-s] 파일명*
- -s 옵션 : sun
3) 파일 시스템 구조
(1) 부트 블록(Boot block)
- 파일 시스템 시작부에 위치하고 보통 첫 번째 섹터를 차지
- 부트스트랩 코드가 저장되는 블록
(2) 슈퍼 블록(Super block)
- 전체 파일 시스템에 대한 * 정보를 저장
- *정보 : 총 블록 수, 사용 가능한 i-노드 수, 사용 가능한 블록 비트 맵, 블록의 크기, 사용 중인 블록 수, 사용 가능한 블록 수 등
(3) i-리스트
- 각 파일을 나타내는 모든 i-노드들의 리스트
- 한 블록은 약 40개 정도의 i-노드를 포함
(4) 데이터 블록(Data block) : 파일의 내용(데이터)을 저장하기 위한 블록들
12.2 파일 상태 정보와 i-노드
1) 파일 상태
- 파일 상태
- 파일에 대한 모든 정보
- 블록 수, 파일 타입, 접근권한, 링크 수, 파일 소유자의 사용자ID, 그룹ID, 파일 크기, 최종 수정 시간
$ ls -l test.txt
4 -rw-rw-r-- 1 yeonjae yeonjae 2088 12월 21일 23:23 test.txt
4(블록 수) -(파일타입)rw-rw-r--(접근권한) 1(링크 수) yeonjae(사용자ID) yeonjae(그룹ID) 2088(파일 크기) 12월 21일 23:23(최종 수정 시간) test.txt(파일 이름)
- stat 명령어 : 파일에 대해 자세한 상태 정보를 출력한다.
$ stat [옵션] 파일
2) i-노드
- 하나의 파일은 하나의 i-노드를 갖는다.
- 파일에 대한 모든 정보를 가지고 있다.
파일 상태 정보 | 의미 |
블록 수 | 파일을 구성하는 블록의 개수 (K 바이트 단위) |
파일 종류 | 파일 종류 |
접근권한 | 파일에 대한 소유자, 그룹, 기타 사용자의 읽기,쓰기, 실행 권한 |
하드 링크 수 | 파일에 대한 하드 링크 수 |
소유자 및 그룹 | 파일의 소유자 ID 및 소유자가 속한 그룹 ID |
파일 크기 | 파일의 크기 |
최종 접근 시간 | 파일을 최후로 접근한 시간 |
최종 수정 시간 | 파일을 생성 혹은 최후로 수정한 시간 |
데이터 블록 주소 | 실제 데이터가 저장된 데이터 블록의 주소 |
3) i-노드와 블록 포인터
- 블록 포인터
- 데이터 블록에 대한 포인터 : 파일의 내용을 저장하기 위해 할당된 데이터 블록의 주소
- 하나의 i-노드 내의 블록 포인터
- 직접 블록 포인터 : 12개
- 간접 블록 포인터 : 12개
- 이중 간접 블록 포인터 : 1개
12.3 디렉터리의 구현
- 디렉터리 엔트리
#icnlude <direct.h>
struct direct {
ino_t d_ino; // i-노드 번호
char d_name[NAME_MAX+1]; // 파일 이름
}
- 디렉터리를 위한 별도의 구조는 없음. -> 디렉터리는 일종의 파일
- 파일처럼 하나의 i-노드로 표현
- 디렉터리의 내용 : 디렉터리 엔트리(파일 이름, i-노드)
12.4 링크의 구현
1) 링크
- 기존 파일에 대한 또 하나의 새로운 이름
- 사용법
$ ln [-s] 파일1 파일2
: 파일1에 대한 새로운 이름(링크)으로 파일2를 만든다. (-s 옵션 : 심볼릭 링크)
$ ln [-s] 파일1 디렉터리
: 파일1에 대한 링크를 지정된 디렉터리에 같은 이름으로 만들어준다.
2) 하드링크
- 기존 파일에 대한 새로운 이름이라고 생각할 수 있다.
- 실제로 기존 파일을 대표하는 i-노드를 가리켜 구현
3) 심볼릭 링크
- 다른 파일을 가리키고 있는 별도의 파일
- 실제 파일의 경로명을 저장하고 있는 일종의 특수 파일 -> 이 경로명이 다른 파일에 대한 간접적인 포인터 역할을 함.
12.5 C 파일 입출력
1) 시스템 호출 (system call)
- 시스템 호출은 유닉스 커널에 서비스를 요청하기 위한 프로그래밍 인터페이스
- 응용 프로그램은 시스템 호출을 통해서 유닉스 커널에 서비스를 요청한다.
2) 파일
- c 프로그램에서 파일의 필요성
- 변수에 저장된 정보들은 실행이 끝나면 전부 사라짐
- 정보를 영속적으로 저장하기 위해서는 파일에 저장해야 한다.
- 유닉스 파일 : 모든 데이터를 연속된 바이트 형태로 저장한다.
3) C언어의 파일 종류
- 텍스트 파일 (text file)
- 사람들이 읽을 수 있는 문자들을 저장하고 있는 파일
- 텍스트 파일에서 "한 줄의 끝"을 나타내는 표현은 파일이 읽어들여질 때, C 내부의 방식으로 변환된다.
- 이진 파일 (binary file)
- 모든 데이터는 있는 그대로 바이트의 연속으로 저장
- 이진 파일을 이용하여 메모리에 저장된 변수 값 형태 그대로 파일에 저장할 수 있다.
4) 파일 입출력
- C언어의 파일 입출력 과정
- 파일 열기 : fopen() 함수 이용
- 파일 입출력 : 다양한 파일 입출력 함수 ㅏ용
- 파일 닫기 : fclose() 함수 사용
(1) 파일 열기
- 파일을 사용하기 위해서는 반드시 먼저 파일 열기(fopen) 필요
- 파일 열기를 하면 FILE 구조체에 대한 포인터가 리턴된다.
- FILE 포인터는 열린 파일을 지정한다.
- 함수 fopen() : 파일 열기를 한다. 열린 파일을 나타내는 FILE 포인터를 반환하며 오류가 발생하면 NULL을 반환한다.
FILE *fopen(const char *filename, const char *mode);
- 모드
모드 | 의미 | 파일이 없으면 | 파일이 있으면 |
"r" | 읽기 전용 (read) | NULL 반환 | 정상 동작 |
"w" | 쓰기 전용 (write) | 새로 생성 | 기존 내용 삭제 |
"a" | 추가 쓰기 (append) | 새로 생성 | 기존 내용 뒤에 추가 |
"r+" | 읽기와 쓰기 | NULL 반환 | 정상 동작 |
"w+" | 읽기와 쓰기 | 새로 생성 | 기존 내용 삭제 |
"a+" | 추가를 위한 읽기와 쓰기 | 새로 생성 | 기존 내용 뒤에 추가 |
(2) 스트림과 파일 구조체
- 스트림(stream) : 파일이 열리면 스트림이라 한다.
- FILE 구조체
- stdio.h에 정의되어 있음.
- 열린 파일의 현재 상태를 나타내는 필드 변수들
- 특히 파일 입출력에 사용되는 버퍼 관련 변수들
typedf struct {
int cnt; // 버퍼에 남은 문자 수
unsigned char *base; // 버퍼 시작
unsigned char *ptr; // 버퍼의 현재 포인터
unsigned flag ; // 파일 접근 모드
int fd; // 열린 파일 디스크립터
} FILE; // FILE 구조체
(3) 표준 입출력 스트림 : stdin(표준 입력), stdout (표준 출력) , stderr (표준 오류)
- C 프로그램이 실행되면 자동으로 열리고 프로그램이 종료될 때는 자동으로 닫힘.
표준 입출력 스트림 | 설명 | 가리키는 장치 |
stdin | 표준입력에 대한 FILE 포인터 | 키보드 |
stdout | 표준출력에 대한 FILE 포인터 | 모니터 |
stderr | 표준오류에 대한 FILE 포인터 | 모니터 |
(4) 파일 닫기
- 파일을 열어서 사용한 후에는 파일을 닫아야 한다.
- 함수 fcolse() : fp가 가리키는 파일을 닫는다. 성공하면 0, 오류일 때는 -1을 반환한다.
12.6 파일 입출력 함수
1) 파일 입출력 함수
표준 입출력 함수 | 파일 입출력 함수 | 기능 |
getchar() | fgetc(), getc() | 문자 단위로 입력하는 함수 |
putchar() | fputc(), putc() | 문자 단위로 출력하는 함수 |
gets() | fgets() | 문자열을 입력하는 함수 |
puts() | fputs() | 문자열을 출력하는 함수 |
scanf() | fscanf() | 자료형에 따라 자료를 입력하는 함수 |
printf() | fprintf() | 자료형에 따라 자료를 출력하는 함수 |
2) 문자 단위 입출력
- fgetc(), fputsc() : 파일에 문자 단위 입출력 가능
- int fgetc(FILE *fp)
- getc 함수는 fp가 지정한 파일에서 한 문자를 읽어서 리턴한다.
- 파일 끝에 도달했을 경우에는 EOF(-1) 리턴
- int fputc(int c, FILE *fp)
- putc 함수는 파일에 한 문자씩 출력
- 리턴값으로 출력되는 문자 리턴
- 출력 시 오류가 발생하면 EOF(-1) 리턴
12.7 명령어 구현
1) cat.c
#include <stdio.h>
/* 텍스트 파일 내용을 표준출력에 프린트 */
int main(int argc, char *argv[])
{
FILE *fp;
int c;
if (argc < 2) fp = stdin; // 명령줄 인수가 없으면 표준입력 사용
else fp = fopen(argv[1], "r"); // 읽기 전용으로 파일 열기
c = getc(fp); // 파일로부터 문자 읽기
while (c != EOF) { // 파일의 끝이 아니면
putc(c, stdout); // 읽은 문자를 표준출력에 출력
c = getc(fp); // 파일로부터 문자 읽기
}
fclose(fp);
return 0;
}
2) copy.c
#include <stdio.h>
/* 파일 복사 프로그램 */
int main(int argc, char *argv[])
{
char c;
FILE *fp1, *fp2;
if (argc!=3) {
fprintf(stderr, "사용법: %s 파일1 파일2\n", argv[0]);
return 1;
}
fp1 = fopen(argv[1], "r");
if (fp1 == NULL) {
fprintf(stderr, "파일 %s 열기 오류\n", argv[1]);
return 2;
}
fp2 = fopen(argv[2], "w");
while ((c = fgetc(fp1)) != EOF) fputc(c, fp2);
fclose(fp1);
fclose(fp2);
return 0;
}
12.8 줄단위 입출력
1) 줄 단위 입출력
- 파일로 한 줄씩 읽기 : 파일로부터 한 줄을 읽어서 문자열 포인터 s에 저장하고 s를 리턴한다.
char* fgets(char *s, int n, FILE *fp);
- 파일에 한 줄씩 읽기 : 문자열 s를 fp가 나타내는 파일에 출력한다. 성공하면 출력한 바이트수를, 실패하면 EOF 값을 리턴한다.
int fputs(const char *s, FILE *fp);
2) line.c // cat -n 구현
#include <stdio.h>
#define MAXLINE 80
int main(int argc, char *argv[]) // 텍스트 파일에 줄 번호를 붙여 프린트
{
FILE *fp;
int line = 0;
char buffer[MAXLINE];
if (argc < 2) exit(1);
if ((fp = fopen(argv[1], "r")) == NULL) {
fprintf(stderr, "파일 열기 오류\n");
exit(2);
}
while (fgets(buffer, MAXLINE, fp) != NULL) // 한 줄 읽기
{
line++;
printf("%3d %s", line, buffer); // 줄 번호와 함께 프린트
}
exit(0);
}
'전공과목 정리 > 리눅스시스템 + 시스템프로그래밍' 카테고리의 다른 글
[리눅스시스템🐧] 14장 시스템 관리 (2) | 2024.01.07 |
---|---|
[리눅스시스템🐧] 13장 프로세스 원리 (2) | 2024.01.07 |
[리눅스시스템🐧] 11장 프로그래밍 환경 (2) | 2024.01.06 |
[리눅스시스템🐧] 10장 Bash 쉘 스크립트 (2) | 2024.01.06 |
[리눅스시스템🐧] 9장 유틸리티 (4) | 2024.01.05 |