前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >文件目录 (一).stat(1)

文件目录 (一).stat(1)

作者头像
franket
发布2021-09-16 09:47:40
6330
发布2021-09-16 09:47:40
举报
文章被收录于专栏:技术杂记技术杂记

前言

UNIX/Linux 的缔造者们将数据的 来源和目标 都抽象为 文件,所以在 UNIX/Linux 系统中 一切皆文件

一切皆文件 不仅仅对磁盘,还包括鼠标,键盘,显示器这些设备

那么目录算不算文件呢?当然算,目录是一种特殊的文件,目录里存放的内容是子目录和文件的索引信息

这里分享一下我在学习文件目录过程中的笔记和心得


概要


代码示例

要求

统计 /home/emacs/c 下有几个C语言源文件 .c ,并找出文件大小最大的那个文件名

Tip: 要求掌握opendir,readdir,closedir,rewinddir用法

代码示例

代码语言:javascript
复制
#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;
}

编译执行

代码语言:javascript
复制
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

代码中有一个这样的定义

代码语言:javascript
复制
DIR *dir=NULL;

DIR 是一种新的结构体

代码语言:javascript
复制
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 有如下定义

代码语言:javascript
复制
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 中对常用的目录操作函数作了声明

代码语言:javascript
复制
/* 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 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 概要
    • 代码示例
      • 要求
      • 代码示例
      • 编译执行
    • DIR
      • 常用的目录操作函数
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档