UNIX/Linux 的缔造者们将数据的 来源和目标 都抽象为 文件,所以在 UNIX/Linux 系统中 一切皆文件
一切皆文件 不仅仅对磁盘,还包括鼠标,键盘,显示器这些设备
那么目录算不算文件呢?当然算,目录是一种特殊的文件,目录里存放的内容是子目录和文件的索引信息
这里分享一下我在学习文件目录过程中的笔记和心得
统计 /home/emacs/c 下有几个C语言源文件 .c ,并找出文件大小最大的那个文件名
Tip: 要求掌握opendir,readdir,closedir,rewinddir用法
#include <stdio.h>
#include <dirent.h> //DIR,opendir,readdir,rewinddir,closedir 的定义和声明都在这个头文件里面
#include <string.h>
#include <sys/stat.h> // stat 结构体的定义在里面
#define MAX 1000
int main()
{
char *dirpath="/home/emacs/c";
DIR *dir=NULL;
struct dirent *de=NULL;
struct stat fs;
int len=0,i=0;
unsigned long maxsize=0;
char filename[MAX]; //各种变量的声明与初始化
if(NULL == (dir=opendir(dirpath))) //打开目录文件并且将目录指针赋给dir,出错则提示并且返回
{
printf("open dir error:%s\n",dirpath);
return -1;
}
while(NULL != (de=readdir(dir))) //遍历目录中的每个条目
{
len=strlen(de->d_name); //获取一个条目的文件名长度存入到len中
if(de->d_name[len-1]=='c' && de->d_name[len-2]=='.' ) //如果一个条目是以'.c'结尾的
{
i++; //使用i进行计数
strcpy(filename,dirpath);
strcat(filename,"/");
strcat(filename,de->d_name); //拼接成一个完整的绝对路径
stat(filename,&fs); //将这个文件的属性信息存入到fs结构体中
if(maxsize < fs.st_size)maxsize=fs.st_size; //总是将最大的文件大小值存入到maxsize变量中
}
}
printf("the total number of .c file is :%d \nthe max size is:%ld\nthe max size .c file are :\n",i,maxsize); //打印出'.c'文件个数,和最大的文件大小
rewinddir(dir); //重新定位目录指针到目录开始处
while(NULL != (de=readdir(dir))) //遍历目录中的每个条目
{
len=strlen(de->d_name); //获取一个条目的文件名长度存入到len中
if(de->d_name[len-1]=='c' && de->d_name[len-2]=='.' ) //如果一个条目是以'.c'结尾的
{
strcpy(filename,dirpath);
strcat(filename,"/");
strcat(filename,de->d_name); //拼接成一个完整的绝对路径
stat(filename,&fs); //将这个文件的属性信息存入到fs结构体中
if(fs.st_size == maxsize)printf("%s\n",filename); //将大小为maxsize的条目进行打印
}
}
closedir(dir); //关闭目录
return 0;
}
emacs@ubuntu:~/c$ alias gtc
alias gtc='gcc -Wall -g -o'
emacs@ubuntu:~/c$ gtc filestat.x filestat.c
emacs@ubuntu:~/c$ ./filestat.x
the total number of .c file is :48
the max size is:5686
the max size .c file are :
/home/emacs/c/sqlite.c
emacs@ubuntu:~/c$
emacs@ubuntu:~/c$ ll -trl *.c | sort -nk 5 | tail -n 5
-rw-r--r-- 1 emacs emacs 5250 2016-12-29 08:23 ftpclient.c
-rw-r--r-- 1 emacs emacs 5352 2016-12-14 01:04 6d.c
-rw-r--r-- 1 emacs emacs 5352 2016-12-14 01:06 toblog.c
-rw-r--r-- 1 emacs emacs 5407 2016-12-29 06:44 ftpserver.c
-rw-r--r-- 1 emacs emacs 5686 2016-12-29 01:39 sqlite.c
emacs@ubuntu:~/c$
编译执行过程中没有报错,从结果来看,符合预期
代码中有一个这样的定义
DIR *dir=NULL;
DIR 是一种新的结构体
emacs@ubuntu:/usr/include$ grep DIR dirent.h | grep typedef
typedef struct __dirstream DIR;
emacs@ubuntu:/usr/include$ grep dirstream * -r
dirent.h:typedef struct __dirstream DIR;
emacs@ubuntu:/usr/include$
可知 DIR 是 __dirstream
的别名,但是头文件中没有有关于 __dirstream
的详细定义
通过查资料,得知 __dirstream
有如下定义
struct __dirstream
{
void *__fd; //`struct hurd_fd' pointer for descriptor.
char *__data; //Directory block.
int __entry_data; //Entry number `__data' corresponds to.
char *__ptr; //Current pointer into the block.
int __entry_ptr; //Entry number `__ptr' corresponds to.
size_t __allocation; //Space allocated for the block.
size_t __size; //Total valid data in the block.
__libc_lock_define (, __lock) //Mutex lock for this structure.
};
总体看来,就是关于一个目录的描述信息
在 dirent.h 中对常用的目录操作函数作了声明
/* Open a directory stream on NAME.
Return a DIR stream on the directory, or NULL if it could not be opened.
This function is a possible cancellation point and therefore not
marked with __THROW. */
extern DIR *opendir (__const char *__name) __nonnull ((1));
/* Close the directory stream DIRP.
Return 0 if successful, -1 if not.
This function is a possible cancellation point and therefore not
marked with __THROW. */
extern int closedir (DIR *__dirp) __nonnull ((1));
/* Read a directory entry from DIRP. Return a pointer to a `struct
dirent' describing the entry, or NULL for EOF or error. The
storage returned may be overwritten by a later readdir call on the
same DIR stream.
If the Large File Support API is selected we have to use the
appropriate interface.
This function is a possible cancellation point and therefore not
marked with __THROW. */
#ifndef __USE_FILE_OFFSET64
extern struct dirent *readdir (DIR *__dirp) __nonnull ((1));
#else
/* Rewind DIRP to the beginning of the directory. */
extern void rewinddir (DIR *__dirp) __THROW __nonnull ((1));
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。