Üye Kayıt Üye Giriş

UNIX / Linux sistemlerinde Dizin Dolaşma İşlemleri


UNIX / Linux sistemlerinde Dizin Dolaşma İşlemleri

 

UNIX/Linux sistemlerinde dizin dolaşma işlemleri için opendir, readdir ve closedir
fonksiyonları kullanılmaktadır. Bu fonksiyonlar POSIX standartlarında belirtilmiştir,
dolayısıyla pek çok sistem tarafından desteklenmektedir. Bu dosyaların prototipleri dirent.h
dosyası içerisindedir.


DOS ve Win32 Sistem programcıları için not: DOS'ta bu işlemi yapan fonksiyonlar findfirst
ve findnext, Win32'de FindFirstFile ve FindNextFile'dır.
POSIX sistemlerinde önce opendir fonksiyonu ile bir handle alınır, sonra readdir her
çağırıldığında yeni bir dizin girişi elde edilir.


DIR *opendir(const char *name);


Fonksiyonun parametresi içeriği elde edilecek dizin ismidir. Örneğin "/home/kaan" gibi
C ve Sistem Programcıları Derneği 21
olmalıdır. Fonksiyon DIR yapısı türünden bir handle alanını dinamik olarak tahsis eder ve
handle değeri ile geri döner. Başarısızlık durumunda fonksiyon NULL değerine geri döner.


struct dirent *readdir(DIR *dir);


Bu fonksiyon her bulduğu dosyanın bilgilerini kendi içerisindeki static yerel bir struct dirent
yapısının içerisine yerleştirir ve bu yapının başlangıç adresiyle geri döner. Fonksiyonun
parametresi opendir fonksiyonundan alınan handle değeridir. Geri dönüş değeri static bir
alanın adresi olduğu için fonksiyon çok girişli (reentered) değildir. Programcı bu fonksiyonu
döngü içerisinde çağırır. Fonksiyon artık dizinde bir dosya bulamadığı zaman NULL değeri
ile geri döner. Dizin dolaşma işlemi bittikten sonra handle alanı closedir fonksiyonu ile
kapatılmalıdır.


int closedir(DIR *dir);
dirent yapısı şöyledir:
struct dirent {
long d_ino;
char d_name[NAME_MAX + 1];
}


Görüldüğü gibi dirent yapısı aslında dizin girişindeki bilgileri vermektedir. UNIX/Linux
sistemlerinin disk organizasyonu çeşitli değişiklikler göstermektedir. Örneğin bazı
sistemlerde her dizin elemanı i-node numarası ve dosya ismi dışında başka bilgiler de
içerebilmektedir. Bu sistemlerde dirent yapısının daha fazla elemanı olabilir. Yukarıda
açıklanan dirent yapısı POSIX standartlarında tanımlanmış olan en küçük durumdur.


/*dizindolas1.c */
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
int main(int argc, char *argv[])
{
DIR *dp;
struct dirent *dinfo;
if (argc == 1) {
printf("Usage mydir <dir name>\n");
exit(1);
}
if (argc >= 3) {
printf("too many argument!\n");
exit(2);
}
dp = opendir(argv[1]);
if (dp == NULL) {
perror("opendir");
exit(1);
}
C ve Sistem Programcıları Derneği 22
while ((dinfo = readdir(dp)) != NULL)
printf("%s\n", dinfo->d_name);
closedir(dp);
}
/* dizindolas2.c */
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <string.h>
#include <sys/stat.h>
#define MAX_PATH_SIZE 1024
void DirWalk(const char *path, void (*Proc) (const char *))
{
char fname[MAX_PATH_SIZE];
struct dirent *de;
struct stat status;
DIR *dir;
if ((dir = opendir(path)) == NULL) {
perror("opendir");
return;
}
while ((de = readdir(dir)) != NULL) {
sprintf(fname, "%s/%s", path, de->d_name);
Proc(fname);
if (strcmp(de->d_name, ".") != 0 &&
strcmp(de->d_name, "..") != 0) {
if (stat(fname, &status) == -1) {
perror("stat");
break;
}
if (S_ISDIR(status.st_mode))
DirWalk(fname, Proc);
}
}
closedir(dir);
}
#if 1
void Disp(const char *name)
{
puts(name);
}
int main(int argc, char *argv[])
{
char fname[MAX_PATH_SIZE];
char *plast;
size_t size;
if (argc != 2) {
printf("Usage: dirtree <path>\n");
exit(1);
C ve Sistem Programcıları Derneği 23
}
strcpy(fname, argv[1]);
plast = strchr(fname, '\0') - 1;
if (plast == '/')
*plast = '\0';
DirWalk(fname, Disp);
return 0;
}
#endif
/* dizindolas3.c */
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <string.h>
#include <sys/stat.h>
#define MAX_NAME_SIZE 1024
void DirWalk(int indent, const char *name, void (*Proc)(int, const char *))
{
char cwd[MAX_NAME_SIZE];
struct dirent *de;
struct stat status;
DIR *dir;
if ((dir = opendir(name)) == NULL) {
perror("opendir");
return;
}
if (getcwd(cwd, MAX_NAME_SIZE) == NULL) {
perror("getcwd");
return;
}
if (chdir(name)) {
perror("chdir");
return;
}
while ((de = readdir(dir)) != NULL) {
Proc(indent, de->d_name);
if (strcmp(de->d_name, ".") != 0 &&
strcmp(de->d_name, "..") != 0) {
if (stat(de->d_name, &status) == -1) {
perror("stat");
break;
}
if (S_ISDIR(status.st_mode))
DirWalk(indent + 1, de->d_name, Proc);
}
}
closedir(dir);
if (chdir(cwd)) {
C ve Sistem Programcıları Derneği 24
perror("chdir");
return;
}
}
#if 1
void Disp(int indent, const char *name)
{
int i;
for (i = 0; i < indent * 2; ++i)
putchar(' ');
puts(name);
}
int main(int argc, char *argv[])
{
char fname[MAX_NAME_SIZE];
char *pLast;
if (argc != 2) {
fprintf(stderr, "Usage: dirtree <path>\n");
exit(1);
}
strcpy(fname, argv[1]);
pLast = strchr(fname, '\0');
if (*pLast == '/' && strlen(fname) != 1)
*pLast = '\0';
DirWalk(0, fname, Disp);
return 0;
}
#endif
/* dizindolas4.cpp */
#include <iostream>
#include <cstdlib>
#include <string>
#include <vector>
#include <algorithm>
#include <cstdio>
#include <dirent.h>
using namespace std;
int main(int argc, char *argv[])
{
DIR *dp;
struct dirent *dinfo;
vector<string> dirlist;
if (argc == 1) {
cerr << "Usage mydir <dir name>\n";
exit(1);
}
if (argc > 3) {
cerr << "too many arguments!\n";
exit(2);
C ve Sistem Programcıları Derneği 25
}
dp = opendir(argv[1]);
if (dp == NULL) {
perror("opendir");
exit(1);
}
while ((dinfo = readdir(dp)) != NULL)
dirlist.push_back(dinfo->d_name);
sort(dirlist.begin(), dirlist.end());
copy(dirlist.begin(), dirlist.end(),
ostream_iterator<string>(cout, "\n"));
closedir(dp);
}

Bilgisayar Dershanesi Ders Sahibi;
Bilgisayar Dershanesi

Yorumlar

Yorum Yapabilmek İçin Üye Girişi Yapmanız Gerekmektedir.

ETİKETLER