유닉스에서 디렉토리 다루기
작성자 : 김문규
최초 작성일 : 2009. 1.21
1. 들어가며
서버 프로그래밍이든 클라이언트 프로그래밍이든 중요하게 다루어 지는 부분은 파일 시스템을 액세스해서 로컬 자원의 정보를 획득하는 것이 아닐까요?
대부분의 프로그래밍 책에서 파일을 열고 닫는 것을 많이 다룹니다. 그런데, 디렉토리에 대한 내용은 많이 보지 못한 것 같습니다.
그래서, 이번 포스트의 주제는 '유닉스에서 디렉토리 다루기' 입니다.
2. 디렉토리 다루기
특정 디렉토리부터 하위 디렉토리에 있는 파일 또는 디렉토리를 검색하는알고리즘을 생각해 보겠습니다.
1) 현재 디렉토리에 존재하는 모든 파일 검색
2) 검색된항목이 파일이면 다음
3) 검색된항목이 디렉토리이면 1)로 가서 다시 검색
이를 구현시에는 다음과 같은 기능이 필요합니다.
1) 현재 디렉토리의 파일리스팅
2) 리스팅된 파일이 일반 파일인지 디렉토리인지 구분하기
3) 재귀 함수 호출
이번 주제에 맞게 1), 2)에 대해서 간단한 예제와 함께 알아 보겠습니다.
1)디렉토리 리스팅 (Directory Listing)
디렉토리 리스팅을 위해서는 다음과 같은 구조체와 함수들을 사용하면 됩니다.
간단한 예제 입니다.
2) 파일 속성 알아내기
파일 속성을 알아내기 위해서는 다음과 같은 구조체와 함수들을 사용하면 됩니다.
모든 필드가 각각의 의미를 가지고 있지만 이번 포스트에서는관심 있는 플래그는 st_mode 입니다. 이 값이 파일의 성격을 알려주는 플래그이거든요.
이 값은 다음의 매크로를 이용해서 확인 가능합니다.
예제코드로 설명한 내용을 확인해 보겠습니다.
3. 마치며
이 방법은 유닉스와 리눅스에서만 사용가능 합니다. 흠흠. 기왕이면 윈도우에서도 사용가능 했으면 좋았을 텐데요.
그럼 즐프하세요.
작성자 : 김문규
최초 작성일 : 2009. 1.21
1. 들어가며
서버 프로그래밍이든 클라이언트 프로그래밍이든 중요하게 다루어 지는 부분은 파일 시스템을 액세스해서 로컬 자원의 정보를 획득하는 것이 아닐까요?
대부분의 프로그래밍 책에서 파일을 열고 닫는 것을 많이 다룹니다. 그런데, 디렉토리에 대한 내용은 많이 보지 못한 것 같습니다.
그래서, 이번 포스트의 주제는 '유닉스에서 디렉토리 다루기' 입니다.
2. 디렉토리 다루기
특정 디렉토리부터 하위 디렉토리에 있는 파일 또는 디렉토리를 검색하는알고리즘을 생각해 보겠습니다.
1) 현재 디렉토리에 존재하는 모든 파일 검색
2) 검색된항목이 파일이면 다음
3) 검색된항목이 디렉토리이면 1)로 가서 다시 검색
이를 구현시에는 다음과 같은 기능이 필요합니다.
1) 현재 디렉토리의 파일리스팅
2) 리스팅된 파일이 일반 파일인지 디렉토리인지 구분하기
3) 재귀 함수 호출
이번 주제에 맞게 1), 2)에 대해서 간단한 예제와 함께 알아 보겠습니다.
1)디렉토리 리스팅 (Directory Listing)
디렉토리 리스팅을 위해서는 다음과 같은 구조체와 함수들을 사용하면 됩니다.
#include <dirent.h>
struct dirent
{
long d_ino; // inode 넘버
off_t d_off; // offset
unsigned short d_reclen; // d_name 길이
char d_name[NAME_MAX+1]; // 파일이름
}
DIR* opendir(const char* name); // 열기
int closedir(DIR* dp); // 닫기
struct dirent* readdir(DIR* dp); // 읽기
struct dirent
{
long d_ino; // inode 넘버
off_t d_off; // offset
unsigned short d_reclen; // d_name 길이
char d_name[NAME_MAX+1]; // 파일이름
}
DIR* opendir(const char* name); // 열기
int closedir(DIR* dp); // 닫기
struct dirent* readdir(DIR* dp); // 읽기
간단한 예제 입니다.
#include <stdio.h>
#include <dirent.h>
#include <dirent.h>
int main (void)
{
DIR *pDir = NULL;
dirent *pFile = NULL;
pDir = opendir(".");
if(!pDir) {
printf("ERROR\n");
}
{
DIR *pDir = NULL;
dirent *pFile = NULL;
pDir = opendir(".");
if(!pDir) {
printf("ERROR\n");
}
while( (pFile = readdir(pDir)) != NULL )
{
printf("%s\n", pFile->d_name);
}
{
printf("%s\n", pFile->d_name);
}
closedir(pDir);
return 0;
}
}
2) 파일 속성 알아내기
파일 속성을 알아내기 위해서는 다음과 같은 구조체와 함수들을 사용하면 됩니다.
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
// 입력 변수만 조금 다를 뿐 기능은 같습니다.
int stat(const char *file_name, struct stat *buf);
int fstat(int filedes, struct stat *buf);
int lstat(const char *file_name, struct stat *buf);
struct stat
{
dev_t st_dev; /* device */
ino_t st_ino; /* inode */
mode_t st_mode; /* protection */
nlink_t st_nlink; /* number of hard links */
uid_t st_uid; /* user ID of owner */
gid_t st_gid; /* group ID of owner */
dev_t st_rdev; /* device type (if inode device) */
off_t st_size; /* total size, in bytes */
unsigned long st_blksize; /* blocksize for filesystem I/O */
unsigned long st_blocks; /* number of blocks allocated */
time_t st_atime; /* time of last access */
time_t st_mtime; /* time of last modification */
time_t st_ctime; /* time of last change */
};
#include <sys/stat.h>
#include <unistd.h>
// 입력 변수만 조금 다를 뿐 기능은 같습니다.
int stat(const char *file_name, struct stat *buf);
int fstat(int filedes, struct stat *buf);
int lstat(const char *file_name, struct stat *buf);
struct stat
{
dev_t st_dev; /* device */
ino_t st_ino; /* inode */
mode_t st_mode; /* protection */
nlink_t st_nlink; /* number of hard links */
uid_t st_uid; /* user ID of owner */
gid_t st_gid; /* group ID of owner */
dev_t st_rdev; /* device type (if inode device) */
off_t st_size; /* total size, in bytes */
unsigned long st_blksize; /* blocksize for filesystem I/O */
unsigned long st_blocks; /* number of blocks allocated */
time_t st_atime; /* time of last access */
time_t st_mtime; /* time of last modification */
time_t st_ctime; /* time of last change */
};
모든 필드가 각각의 의미를 가지고 있지만 이번 포스트에서는관심 있는 플래그는 st_mode 입니다. 이 값이 파일의 성격을 알려주는 플래그이거든요.
이 값은 다음의 매크로를 이용해서 확인 가능합니다.
S_ISLNK(m) is it a symbolic link?
S_ISREG(m) regular file?
S_ISDIR(m) directory?
S_ISCHR(m) character device?
S_ISBLK(m) block device?
S_ISFIFO(m) fifo?
S_ISSOCK(m) socket?
S_ISREG(m) regular file?
S_ISDIR(m) directory?
S_ISCHR(m) character device?
S_ISBLK(m) block device?
S_ISFIFO(m) fifo?
S_ISSOCK(m) socket?
예제코드로 설명한 내용을 확인해 보겠습니다.
#include <stdio.h>
#include <dirent.h>
#include <sys/stat.h>
#include <string.h>
#include <dirent.h>
#include <sys/stat.h>
#include <string.h>
int main (void)
{
DIR *pDir = NULL;
dirent *pFile = NULL;
struct stat buf;
{
DIR *pDir = NULL;
dirent *pFile = NULL;
struct stat buf;
pDir = opendir(".");
if(!pDir) {
printf("ERROR\n");
}
if(!pDir) {
printf("ERROR\n");
}
while( (pFile = readdir(pDir)) != NULL )
{
memset(&buf, 0, sizeof(struct stat));
lstat(pFile->d_name, &buf); // buf에 stat 정보 저장
{
memset(&buf, 0, sizeof(struct stat));
lstat(pFile->d_name, &buf); // buf에 stat 정보 저장
if(S_ISDIR(buf.st_mode)) printf("[DIR]%s\n", pFile->d_name);
else if(S_ISREG(buf.st_mode)) printf("[FILE]%s\n", pFile->d_name);
else printf("[ELSE]%s\n", pFile->d_name);
}
else if(S_ISREG(buf.st_mode)) printf("[FILE]%s\n", pFile->d_name);
else printf("[ELSE]%s\n", pFile->d_name);
}
closedir(pDir);
return 0;
}
}
3. 마치며
이 방법은 유닉스와 리눅스에서만 사용가능 합니다. 흠흠. 기왕이면 윈도우에서도 사용가능 했으면 좋았을 텐데요.
그럼 즐프하세요.
'UNIX_LINUX_C_C++' 카테고리의 다른 글
IBM AIX 에서 IP 주소 알아내기 (0) | 2012.01.13 |
---|---|
unix 에서 dir 함수 사용 - 링크 (0) | 2011.12.19 |
pthread 사용방법 (0) | 2011.11.18 |
UNIX programming examples (0) | 2011.11.18 |
메시지 큐 (0) | 2011.11.12 |