프로그래밍/Linux Programming

[Linux] 디렉토리 처리 함수들 opendir(), readdir(), chdir(), 간단 예제.

K_Coder 2011. 10. 5. 17:27


[Linux] 디렉토리 처리 함수들 opendir(), readdir(), chdir(), getcwd() 간단 예제.
[Linux] 디렉토리 처리 함수들 opendir(), readdir(), chdir(), getcwd() 간단 예제.
[Linux] 디렉토리 처리 함수들 closedir(), rewinddir(), mkdir(), rmdir() 간단 예제.
[Linux] 디렉토리 처리 함수들 closedir(), rewinddir(), mkdir(), rmdir() 간단 예제.


<디렉토리 관리>

 : 디렉토리 포멧은 시스템마다 구현에 차이가 있어서 시스템 의존적이다.

 디렉토리 관련 오퍼레이션을 시스템과 무관하게  할 수 있도록 하기위해 POSIX.1 에 관련 함수들이  정의 되어 있음


* 디렉토리 읽기 함수  --------------------------------

 #include <sys/types.h>
 #include <dirent.h>

opendir()

  DIR *opendir(const char *name);     실패 시 NULL 리턴.

closedir()
  int closedir(DIR *dir);        성공 시 0, 실패시 -1 리턴.

readdir()
  struct dirent *readdir(DIR *dir);   디렉토리 항목을 읽음. 다 읽거나 에러일 때 NULL 리턴함

readdir 함수는 *dir가 가리키는 디렉토리 내 파일 목록의 주소를 반환하고
*dir의 다음 파일 목록을 가르킨다. 파일 목록은 readdir 함수를 반복 호출해서
반환 받은 구조체의 내용을 얻어내면 된다. 파일 목록에는 삭제된 파일의 정보도 포함되어 있으며
구조체 dirent의 변수 d_ino이 0이면 삭제된 파일로 보고 처리해야 함.

dirent.h
struct dirent
{
     long                  d_ino;                                // I-노드 번호
     off_t                   d_off;                                // offset
     unsigned short   d_reclen;                           // 파일 이름 길이
     char                  d_name[NAME_MAX+1];    // 파일 이름
}

I-노드 번호(d_ino)가 0이면 삭제된 파일 이다.

rewinddir()
 void rewinddir(DIR *dir);    디렉토리의 처음 위치로 리셋.

 

opendir(), closedir(), readdir() 을 이용한 디렉토리 안의 목록 보기. ( ls )

 파일과 마찬가지로 opnedir() 시의 정보를 받아 둘 변수가 필요한다. 타입은 DIR.
또한 readdir()을 통해서 해당 내용을 읽어서 가지고 있을 구조체도 필요하다.

디렉토리 안에는 파일의 이름들, 각각의 파일에 대한 정보들이 있기 때문에 구조체로 받는다.

struct dirent 는 dirent.h 안에 정의 되어 있다. 위에 구조체에 대한 내용 설명 있음.

프로그램을 실행하면서 어떤 디렉토리를 열어서 읽을지 값을 줘야하게 되어 있다.
따라서 매개변수가 2개 미만이라면 사용법에 대한 메시지를 출력해주고 종료한다.

opendir()을 이용해서 해당 파일을 여는데 실패시 NULL을 리턴하므로 반환 값이 NULL 이라면
폴더를 열지 못했다는 메시지를 출력하고 종료한다.

정상적으로 열었다면. opendir()로 받은 값(od)를 readdir()에 전달하여 읽기를 시도 한다.
readdir()의 반환 값은 디렉토리 내의 정보들을 갖는 구조체 이다.

위에서 설명했듯이, readdir()을 사용하면 그 폴더 내의 첫번째 주소를 반환한다.
그리고는 다음 주소(구조체)를 가르키고 있다.

반환 받은 구조체에서 d_name. 즉, 파일 또는 디렉토리명을 출력한다.

그리고 다시 해당 디렉토리를 열면 가르키고 있는 주소(구조체)를 반환하고
 다시 다음 주소를 가르키게 되며
 받은 구조체에서 다시 파일의 이름을 출력한다.
꼭 이름이 아니더라고 본인이 출력하고 싶은 내용을 얻으면 된다.

위와 같은 방식을 반복하면서 해당 폴더의 끝. 즉 NULL 값을 리턴 받으면 반복문을 빠져나오고

마지막으로 파일처리와 마찬가지로 디렉토리를 닫아준다.


[opendir(), closedir(), readdir() 을 이용한 디렉토리 안의 목록 보기. ( ls ) 결과]


/usr의 파일명을 출력한 결과이다. 보이다 싶이 정렬이 되어 있지는 않다.






 getcwd() : 현재 작업 디렉토리의 경로 정보를 읽음
 #include <unistd.h>

 char * getcwd(char *buf, size_t size);


chdir() : 현재 디렉토리를 path 가 지정한 곳으로 바꾼다.
 #include <unistd.h>

 int chdir(const char *path);   성공시 0, 실패시 -1 리턴.

 

chdir()과 getcwd() 를 이용한 경로 이동.

if(argc < 2) main의 매개변수 값을 체크해서 예외처리.

chdir(경로) 를 사용한 결과가 0이 나오면 경로 이동 성공.
getcwd(경로 저장할 공간, 경로를 읽을 글자 수) 를 사용해서 현재 경로를 buf에 담는다.

현재 경로의 길이가 길 수도 있으며. 경로에서 몇 글자를 읽을지 지정할 수 있다.

buf에 담은 내용을 출력하면 경로 확인 완료.

chdir()의 결과가 0이 아닌 경우 해당 경로가 없거나 문제가 있으므로 에러 메시지를 출력 후 종료.


[chdir()과 getcwd() 를 이용한 경로 이동 결과]


pwd를 이용해 현재 경로를 체크했다.
그리고 프로그램을 통해 .. 으로 상위 경로로 이동 시켰다.
path에 상위경로가 찍힌 것을 볼 수 있다.

단, chdir()은 프로그램 내에서 경로를 이동해 작업하고 하는 방식이다.
따라서 명령 프롬프트가 바뀌지는 않는다. 명령 프로프트를 바꾸려면 좀 더 부가적인 내용이 필요한다.

 



mkdir() : pathname 에 대한 디렉토리를 만듦
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <fcntl.h>
 #include <unistd.h>

 int mkdir(const char *pathname, mode_t mode);


rmdir() : pathname 의 디렉토리를 삭제함.  이때 디렉토리는 비어 있어야 함
 #include <unistd.h>

 int rmdir(const char *pathname);

 

유용한 정보가 되셨다면 아래 손가락 버튼 한번 눌러주세요 ^-^