Não é difícil. Já fiz isso algumas vezes, mas é claro que de cabeça não vou ficar guardando isso: pra que existem os comandos
man
e apropos
?Os cabeçalhos necessários para leitura de diretório são:
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <unistd.h>
Precisamos também das bibliotecas
string.h
– ou string
em C++ –, time.h
e stdio.h
– ou iostream
em C++.A função para abertura de um diretório é
opendir()
, recebe como parâmetro uma string representando o nome do diretório e retorna um ponteiro para descritor de diretório, DIR
.Para abrir um diretório:
DIR *dir = opendir(dirname);
A função
readdir()
reitera sobre o diretório, retornando um ponteiro para estrutura do tipo dirent
ou NULL
caso não haja mais entradas.Então uma forma de reiterar sobre um diretório é:
struct dirent *ent; while (ent = readdir(dir)) {
...}
Ao final da reiteração, é preciso fechar o diretório:
closedir(dir);
A estrutura
dirent
é declarada assim:struct dirent {
long d_ino; /* número de inodes */
off_t d_off; /* offset para este dirent */
unsigned short d_reclen; /* tamanho de d_name */
char d_name[NAME_MAX+1]; /* nome do arquivo */
};
Se quiser mais informações sobre cada entrada, crie uma estrutura
stat
para a entrada. Para tanto use a função stat()
:struct stat buf;
char aux[256];
strcpy(aux, dirname);
#ifdef WIN32
strcat(aux, "\\");
#else
strcat(aux, "/");
#endif
strcat(aux, ent->d_name);
stat(aux, &buf);
A estrutura
stat
é definida assim:struct stat {
dev_t st_dev; /* ID do dispositivo */
ino_t st_ino; /* número do inode */
mode_t st_mode; /* modo de proteção */
nlink_t st_nlink; /* número de hard links */
uid_t st_uid; /* ID do usuário dono */
gid_t st_gid; /* ID do grupo dono */
dev_t st_rdev; /* ID do dispositivo se for arquivo especial */
off_t st_size; /* tamanho total em bytes */
blksize_t st_blksize; /* tamanho do bloco */
blkcnt_t st_blocks; /* número de blocos alocados */
time_t st_atime; /* hora do último acesso */
time_t st_mtime; /* hora da última modificação */
time_t st_ctime; /* hora da última troca de estado */
};
Um campo interessante é
st_mode
. O modo de acesso pode ser obtido como:char *acc = (char *) malloc(sizeof(char) * 6);
sprintf(acc, "0%o", buf.st_mode % 4096);
E é possível saber se a entrada se trata de um arquivo ou diretório de forma similar:
int isDir = buf.st_mode & S_IFDIR;
É possível usar as funções da biblioteca
time.h
para facilitar a leitura dos campos st_atime
, st_mtime
e st_ctime
.Por exemplo, para exibir a última modificação de um arquivo:
printf("Última modificação: %s", ctime( &(buf.st_mtime) ));
Espero que este artigo seja útil. =)
[]'s
Cacilhas La Batalema