Accessing a directory and all the files within it
来源:互联网 发布:天庭淘宝店 无常著txt 编辑:程序博客网 时间:2024/06/05 19:54
To access a directory, and the files within it, is a very compiler/OS specific task. It's not practicable to show how to do this for all variations, so here are some examples for various compilers.
The basic principle is the same for each, start by attaching to the base directory, and then the first file within it. Then repeatedly ask for the "next" file, if it's a directory, move into it, and start over. Recursion is used to achieve this, and this code provides a good example of that technique which is nice to follow through.
This first example, adapted from a post by Salem, if I remember correctly, works on Borland 5.5 command line compiler (and possibly other versions). It simply performs a recursive search of all directories on the current drive, looking for files matching the name provided by the user. The filename comparison function uses strcmp(), which is case sensitive, so watch out for that if you use this code.
Instead of printing each matching file, the walker() function could be adapted to take a function pointer as an argument, and then call that function for each matching file. This would make the code more versatile, but naturally, it's up to you what you do with it.
#include <stdio.h>
#include <dir.h>
#include <string.h>
#define ALL_ATTS (FA_DIREC | FA_ARCH)
void walker(const char *, const char *);
void walker(const char *path, const char *findme)
{
struct ffblk finder;
unsigned int res;
chdir(path);
for (res = findfirst("*.*", &finder, ALL_ATTS); res == 0; res = findnext(&finder))
{
if (strcmp(finder.ff_name, ".") == 0) continue; /* current dir */
if (strcmp(finder.ff_name, "..") == 0) continue; /* parent dir */
/*
* If its a directory, examine it
* else compare the filename with the one we're looking for
*/
if (finder.ff_attrib & FA_DIREC)
{
char newpath[MAXPATH];
strcpy(newpath, path);
strcat(newpath, "\\");
strcat(newpath, finder.ff_name);
chdir(finder.ff_name);
walker(newpath, findme);
chdir("..");
}
else
{
if (strcmp(finder.ff_name, findme) == 0)
{
printf("Found in: %s\n", path);
}
}
}
}
int main(void)
{
const char *root = "\\";
char buf[BUFSIZ];
printf ("This program will find a file on the current drive.\n"
"Enter the name of the file to look for: ");
fflush(stdout);
if (fgets(buf, sizeof(buf), stdin))
{
strtok(buf, "\n"); /* Remove the newline character */
walker(root, buf);
}
return(0);
}
/*
* Program output:
This program will find a file on the current drive.
Enter the name of the file to look for: MyFile.txt
Found in: \\Temp\MySubDir
*
*/
This next example supplied by vVv was written for the *nix FAQ, so it should be suitable for POSIX compliant compilers/systems. It also compiles on Borland 5.5
/*
* This program displays the names of all files in the current directory.
*/
#include <dirent.h>
#include <stdio.h>
int main(void)
{
DIR *d;
struct dirent *dir;
d = opendir(".");
if (d)
{
while ((dir = readdir(d)) != NULL)
{
printf("%s\n", dir->d_name);
}
closedir(d);
}
return(0);
}
The following is an expanded example for Unix systems.
#include <dirent.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
int walker( char *searching, char *result ) {
DIR *d;
struct dirent *dir;
d = opendir( "." );
if( d == NULL ) {
return 1;
}
while( ( dir = readdir( d ) ) ) {
if( strcmp( dir->d_name, "." ) == 0 ||
strcmp( dir->d_name, ".." ) == 0 ) {
continue;
}
if( dir->d_type == DT_DIR ) {
chdir( dir->d_name );
walker( searching, result );
chdir( ".." );
} else {
if( strcmp( dir->d_name, searching ) == 0 ) {
int len;
getcwd( result, MAXPATHLEN );
len = strlen( result );
snprintf( result + len, MAXPATHLEN - len, "/%s", dir->d_name );
break;
}
}
}
closedir( d );
return *result == 0;
}
int main( ) {
char buf[MAXPATHLEN] = { 0 };
if( walker( "lame", buf ) == 0 ) {
printf( "Found: %s\n", buf );
} else {
puts( "Not found" );
}
return 0;
}
And now a Win32 example
// xtree.cpp : Defines the entry point for the console application.
//
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
void errormessage(void)
{
LPVOID lpMsgBuf;
FormatMessage
(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) & lpMsgBuf,
0,
NULL
);
fprintf(stderr, "%s\n", (char*)lpMsgBuf);
LocalFree(lpMsgBuf);
}
void format_time(FILETIME *t, char *buff)
{
FILETIME localtime;
SYSTEMTIME sysloc_time;
FileTimeToLocalFileTime(t, &localtime);
FileTimeToSystemTime(&localtime, &sysloc_time);
sprintf
(
buff,
"%4d/%02d/%02d %02d:%02d:%02d",
sysloc_time.wYear,
sysloc_time.wMonth,
sysloc_time.wDay,
sysloc_time.wHour,
sysloc_time.wMinute,
sysloc_time.wSecond
);
}
void format_attr(DWORD attr, char *buff)
{
*buff++ = attr & FILE_ATTRIBUTE_ARCHIVE ? 'A' : '-';
*buff++ = attr & FILE_ATTRIBUTE_SYSTEM ? 'S' : '-';
*buff++ = attr & FILE_ATTRIBUTE_HIDDEN ? 'H' : '-';
*buff++ = attr & FILE_ATTRIBUTE_READONLY ? 'R' : '-';
*buff++ = attr & FILE_ATTRIBUTE_DIRECTORY ? 'D' : '-';
*buff++ = attr & FILE_ATTRIBUTE_ENCRYPTED ? 'E' : '-';
*buff++ = attr & FILE_ATTRIBUTE_COMPRESSED ? 'C' : '-';
*buff = '\0';
}
struct flist
{
int num_entries;
int max_entries;
WIN32_FIND_DATA *files;
};
void addfile(flist *list, WIN32_FIND_DATA data)
{
if (list->num_entries == list->max_entries)
{
int newsize = list->max_entries == 0 ? 16 : list->max_entries * 2;
WIN32_FIND_DATA *temp = (WIN32_FIND_DATA *) realloc(list->files, newsize * sizeof(WIN32_FIND_DATA));
if (temp == NULL)
{
fprintf(stderr, "Out of memory\n");
exit(1);
}
else
{
list->max_entries = newsize;
list->files = temp;
}
}
list->files[list->num_entries++] = data;
}
int sortfiles(const void *a, const void *b)
{
const WIN32_FIND_DATA *pa = (WIN32_FIND_DATA *) a;
const WIN32_FIND_DATA *pb = (WIN32_FIND_DATA *) b;
int a_is_dir = pa->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
int b_is_dir = pb->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
if (a_is_dir ^ b_is_dir)
{
// one of each, prefer the directories first
if (a_is_dir) return(-1);
if (b_is_dir) return(+1);
return(0);
}
else
{
// both files, or both directories - return the strcmp result
return(strcmp(pa->cFileName, pb->cFileName));
}
}
void doit(char *root)
{
flist list = { 0, 0, NULL };
HANDLE h;
WIN32_FIND_DATA info;
int i;
// build a list of files
h = FindFirstFile("*.*", &info);
if (h != INVALID_HANDLE_VALUE)
{
do
{
if (!(strcmp(info.cFileName, ".") == 0 || strcmp(info.cFileName, "..") == 0))
{
addfile(&list, info);
}
} while (FindNextFile(h, &info));
if (GetLastError() != ERROR_NO_MORE_FILES) errormessage();
FindClose(h);
}
else
{
errormessage();
}
// sort them
qsort(list.files, list.num_entries, sizeof(list.files[0]), sortfiles);
// print out in sorted order
int numdirs = 0;
for (i = 0; i < list.num_entries; i++)
{
char t1[50], t2[50], t3[50], a[10];
format_time(&list.files[i].ftCreationTime, t1);
format_time(&list.files[i].ftLastAccessTime, t2);
format_time(&list.files[i].ftLastWriteTime, t3);
format_attr(list.files[i].dwFileAttributes, a);
if (list.files[i].dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
// 'null' date for directory access times, which change each time
// we run this tool
sprintf(t2, "%4d/%02d/%02d %02d:%02d:%02d", 2000, 1, 1, 0, 0, 0);
}
printf("%s %10ld %s %s %s %s\\%s\n", a, list.files[i].nFileSizeLow, t1, t2, t3, root, list.files[i].cFileName);
if (list.files[i].dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) numdirs++;
}
// now process all the sub-dirs
// free all the files first, to save a bit of space
// the sort function will have put them all at the end.
list.files = (WIN32_FIND_DATA *) realloc(list.files, numdirs * sizeof(WIN32_FIND_DATA));
for (i = 0; i < numdirs; i++)
{
char newroot[MAX_PATH];
sprintf(newroot, "%s\\%s", root, list.files[i].cFileName);
SetCurrentDirectory(list.files[i].cFileName);
doit(newroot);
SetCurrentDirectory("..");
}
// free the remainder
free(list.files);
}
void banner(void)
{
// 12345678901234567890
printf("Attribs ");
printf(" Size ");
printf(" CreationTime ");
printf(" LastAccessTime ");
printf(" LastWriteTime ");
printf("Filename\n");
}
int main(int argc, char *argv[])
{
if (argc > 1)
{
char olddir[MAX_PATH];
if (GetCurrentDirectory(MAX_PATH, olddir) == 0)
{
errormessage();
exit(1);
}
if (!SetCurrentDirectory(argv[1]))
{
errormessage();
exit(1);
}
banner();
doit(".");
SetCurrentDirectory(olddir);
}
else
{
banner();
doit(".");
}
return(0);
The basic principle is the same for each, start by attaching to the base directory, and then the first file within it. Then repeatedly ask for the "next" file, if it's a directory, move into it, and start over. Recursion is used to achieve this, and this code provides a good example of that technique which is nice to follow through.
This first example, adapted from a post by Salem, if I remember correctly, works on Borland 5.5 command line compiler (and possibly other versions). It simply performs a recursive search of all directories on the current drive, looking for files matching the name provided by the user. The filename comparison function uses strcmp(), which is case sensitive, so watch out for that if you use this code.
Instead of printing each matching file, the walker() function could be adapted to take a function pointer as an argument, and then call that function for each matching file. This would make the code more versatile, but naturally, it's up to you what you do with it.
#include <stdio.h>
#include <dir.h>
#include <string.h>
#define ALL_ATTS (FA_DIREC | FA_ARCH)
void walker(const char *, const char *);
void walker(const char *path, const char *findme)
{
struct ffblk finder;
unsigned int res;
chdir(path);
for (res = findfirst("*.*", &finder, ALL_ATTS); res == 0; res = findnext(&finder))
{
if (strcmp(finder.ff_name, ".") == 0) continue; /* current dir */
if (strcmp(finder.ff_name, "..") == 0) continue; /* parent dir */
/*
* If its a directory, examine it
* else compare the filename with the one we're looking for
*/
if (finder.ff_attrib & FA_DIREC)
{
char newpath[MAXPATH];
strcpy(newpath, path);
strcat(newpath, "\\");
strcat(newpath, finder.ff_name);
chdir(finder.ff_name);
walker(newpath, findme);
chdir("..");
}
else
{
if (strcmp(finder.ff_name, findme) == 0)
{
printf("Found in: %s\n", path);
}
}
}
}
int main(void)
{
const char *root = "\\";
char buf[BUFSIZ];
printf ("This program will find a file on the current drive.\n"
"Enter the name of the file to look for: ");
fflush(stdout);
if (fgets(buf, sizeof(buf), stdin))
{
strtok(buf, "\n"); /* Remove the newline character */
walker(root, buf);
}
return(0);
}
/*
* Program output:
This program will find a file on the current drive.
Enter the name of the file to look for: MyFile.txt
Found in: \\Temp\MySubDir
*
*/
This next example supplied by vVv was written for the *nix FAQ, so it should be suitable for POSIX compliant compilers/systems. It also compiles on Borland 5.5
/*
* This program displays the names of all files in the current directory.
*/
#include <dirent.h>
#include <stdio.h>
int main(void)
{
DIR *d;
struct dirent *dir;
d = opendir(".");
if (d)
{
while ((dir = readdir(d)) != NULL)
{
printf("%s\n", dir->d_name);
}
closedir(d);
}
return(0);
}
The following is an expanded example for Unix systems.
#include <dirent.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
int walker( char *searching, char *result ) {
DIR *d;
struct dirent *dir;
d = opendir( "." );
if( d == NULL ) {
return 1;
}
while( ( dir = readdir( d ) ) ) {
if( strcmp( dir->d_name, "." ) == 0 ||
strcmp( dir->d_name, ".." ) == 0 ) {
continue;
}
if( dir->d_type == DT_DIR ) {
chdir( dir->d_name );
walker( searching, result );
chdir( ".." );
} else {
if( strcmp( dir->d_name, searching ) == 0 ) {
int len;
getcwd( result, MAXPATHLEN );
len = strlen( result );
snprintf( result + len, MAXPATHLEN - len, "/%s", dir->d_name );
break;
}
}
}
closedir( d );
return *result == 0;
}
int main( ) {
char buf[MAXPATHLEN] = { 0 };
if( walker( "lame", buf ) == 0 ) {
printf( "Found: %s\n", buf );
} else {
puts( "Not found" );
}
return 0;
}
And now a Win32 example
// xtree.cpp : Defines the entry point for the console application.
//
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
void errormessage(void)
{
LPVOID lpMsgBuf;
FormatMessage
(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) & lpMsgBuf,
0,
NULL
);
fprintf(stderr, "%s\n", (char*)lpMsgBuf);
LocalFree(lpMsgBuf);
}
void format_time(FILETIME *t, char *buff)
{
FILETIME localtime;
SYSTEMTIME sysloc_time;
FileTimeToLocalFileTime(t, &localtime);
FileTimeToSystemTime(&localtime, &sysloc_time);
sprintf
(
buff,
"%4d/%02d/%02d %02d:%02d:%02d",
sysloc_time.wYear,
sysloc_time.wMonth,
sysloc_time.wDay,
sysloc_time.wHour,
sysloc_time.wMinute,
sysloc_time.wSecond
);
}
void format_attr(DWORD attr, char *buff)
{
*buff++ = attr & FILE_ATTRIBUTE_ARCHIVE ? 'A' : '-';
*buff++ = attr & FILE_ATTRIBUTE_SYSTEM ? 'S' : '-';
*buff++ = attr & FILE_ATTRIBUTE_HIDDEN ? 'H' : '-';
*buff++ = attr & FILE_ATTRIBUTE_READONLY ? 'R' : '-';
*buff++ = attr & FILE_ATTRIBUTE_DIRECTORY ? 'D' : '-';
*buff++ = attr & FILE_ATTRIBUTE_ENCRYPTED ? 'E' : '-';
*buff++ = attr & FILE_ATTRIBUTE_COMPRESSED ? 'C' : '-';
*buff = '\0';
}
struct flist
{
int num_entries;
int max_entries;
WIN32_FIND_DATA *files;
};
void addfile(flist *list, WIN32_FIND_DATA data)
{
if (list->num_entries == list->max_entries)
{
int newsize = list->max_entries == 0 ? 16 : list->max_entries * 2;
WIN32_FIND_DATA *temp = (WIN32_FIND_DATA *) realloc(list->files, newsize * sizeof(WIN32_FIND_DATA));
if (temp == NULL)
{
fprintf(stderr, "Out of memory\n");
exit(1);
}
else
{
list->max_entries = newsize;
list->files = temp;
}
}
list->files[list->num_entries++] = data;
}
int sortfiles(const void *a, const void *b)
{
const WIN32_FIND_DATA *pa = (WIN32_FIND_DATA *) a;
const WIN32_FIND_DATA *pb = (WIN32_FIND_DATA *) b;
int a_is_dir = pa->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
int b_is_dir = pb->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
if (a_is_dir ^ b_is_dir)
{
// one of each, prefer the directories first
if (a_is_dir) return(-1);
if (b_is_dir) return(+1);
return(0);
}
else
{
// both files, or both directories - return the strcmp result
return(strcmp(pa->cFileName, pb->cFileName));
}
}
void doit(char *root)
{
flist list = { 0, 0, NULL };
HANDLE h;
WIN32_FIND_DATA info;
int i;
// build a list of files
h = FindFirstFile("*.*", &info);
if (h != INVALID_HANDLE_VALUE)
{
do
{
if (!(strcmp(info.cFileName, ".") == 0 || strcmp(info.cFileName, "..") == 0))
{
addfile(&list, info);
}
} while (FindNextFile(h, &info));
if (GetLastError() != ERROR_NO_MORE_FILES) errormessage();
FindClose(h);
}
else
{
errormessage();
}
// sort them
qsort(list.files, list.num_entries, sizeof(list.files[0]), sortfiles);
// print out in sorted order
int numdirs = 0;
for (i = 0; i < list.num_entries; i++)
{
char t1[50], t2[50], t3[50], a[10];
format_time(&list.files[i].ftCreationTime, t1);
format_time(&list.files[i].ftLastAccessTime, t2);
format_time(&list.files[i].ftLastWriteTime, t3);
format_attr(list.files[i].dwFileAttributes, a);
if (list.files[i].dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
// 'null' date for directory access times, which change each time
// we run this tool
sprintf(t2, "%4d/%02d/%02d %02d:%02d:%02d", 2000, 1, 1, 0, 0, 0);
}
printf("%s %10ld %s %s %s %s\\%s\n", a, list.files[i].nFileSizeLow, t1, t2, t3, root, list.files[i].cFileName);
if (list.files[i].dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) numdirs++;
}
// now process all the sub-dirs
// free all the files first, to save a bit of space
// the sort function will have put them all at the end.
list.files = (WIN32_FIND_DATA *) realloc(list.files, numdirs * sizeof(WIN32_FIND_DATA));
for (i = 0; i < numdirs; i++)
{
char newroot[MAX_PATH];
sprintf(newroot, "%s\\%s", root, list.files[i].cFileName);
SetCurrentDirectory(list.files[i].cFileName);
doit(newroot);
SetCurrentDirectory("..");
}
// free the remainder
free(list.files);
}
void banner(void)
{
// 12345678901234567890
printf("Attribs ");
printf(" Size ");
printf(" CreationTime ");
printf(" LastAccessTime ");
printf(" LastWriteTime ");
printf("Filename\n");
}
int main(int argc, char *argv[])
{
if (argc > 1)
{
char olddir[MAX_PATH];
if (GetCurrentDirectory(MAX_PATH, olddir) == 0)
{
errormessage();
exit(1);
}
if (!SetCurrentDirectory(argv[1]))
{
errormessage();
exit(1);
}
banner();
doit(".");
SetCurrentDirectory(olddir);
}
else
{
banner();
doit(".");
}
return(0);
}
From: www.Cprogramming.com
- Accessing a directory and all the files within it
- Display a Directory Tree of all Subdirectories and Files
- CSharp Algorithm - Recursive method (Iterate all directories and files in a directory)
- Reading a Directory's Contents including child directorys and files.
- All the example files
- all the characteristics of the Eagle Creek Centerline construct it a sensible buy and healthy value your money.
- A Novel Approach to Improvingthe Efficiency of Storing and Accessing Small Files on Hadoop: a Case S
- How do I use the locate command within a specified directory?
- How to create a custom directory for app files inside the ~/Library/Application Support directory.
- chanel outlet online I am a flare of Harry Potter and all the main characters among it
- ccah-500 第42题 want to set and enforce a block size of 128MB for all new files written to the cluster
- --initialize specified but the data directory has files in it. Aborting
- MySQL5.7 启动报错:initialize specified but the data directory has files in it. Aborting.
- mysql报错:--initialize specified but the data directory has files in it. Aborting.
- List all in the Directory
- Spatial index is slow when trying to find all the points within a range of a geocode.
- JDeveloper JSP files must reside in the server root directory or a subdirectory
- What is the maximum number of files allowed in a HDFS directory?
- Inside Qt Series (二-四):对象数据存储
- 基于fusion的DirectFB消息流 .
- mysql当天日期函数使用小结
- oracle 动态语句中的单引号问题,及动态创建多张表
- Asp.net_保持页面滚动条位置
- Accessing a directory and all the files within it
- 功夫不负有心人,坚持总会有惊喜!
- 清醒纪
- 【JAVA陷阱与缺陷-->规则】(一)基础篇
- mysql的alter语句用法
- Accessing command line parameters/arguments
- Ubuntu中关闭按钮位置的改变
- X509证书
- 网站服务器Win2003系统网络安全设置全攻略