镜缘浮影 小人本住在 苏州的城外 家里有屋又有田 生活乐无边

文件目录 (二).dirent

2017-01-04
wilmosfang
c
原文地址 http://soft.dog/2017/01/04/c-filestat-02/

前言

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

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

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

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


概要


代码示例

要求

  • 1、 用程序创建6个文件(要求用循环),路径”/home/emacs/file/filedir”,文件名分别为f11、f21、f32、f41、f52、h42. 将int型数字100,200,300,400,500,600分别存到这6个文件中。

  • 2、遍历路径”/home/emacs/file/filedir”,求文件名首字母是f、末尾是2的文件中的数字和。

  • 3、删除文件名末尾是2的所有文件。

代码示例

#include <stdio.h>
#include <dirent.h>
#include <string.h>
#include <unistd.h> //close, write, read 等文件操作需要这个头
#include <fcntl.h> //open 等文件操作需要这个头
#define MAX 1000


int main()
{
  char *path="/home/emacs/file/filedir";
  char *filename[6]={"f11","f21","f32","f41","f52","h42"};
  char fn[MAX];
  int i=0,fd=0,res=-1,value=0,sum=0,len=0;
  DIR *dir=NULL;
  struct dirent *de=NULL; //定义变量和初始化 ,关于 DIR 和 dirent 结构体的内容可以参看前面一篇博客


  //part 1
  for(i=0;i<6;i++) //循环6次
  {
    strcpy(fn,path);
    strcat(fn,"/");
    strcat(fn,filename[i]); //拼接出文件的全路径
    if(-1 == (fd=open(fn,O_RDWR|O_CREAT|O_TRUNC,0644))) //打开文件,有问题则提示,并且返回
    {
    printf("cannot open file:%s\n",fn);
    return res;
    }
    value=(i+1)*100; //构造值
    if ( sizeof(int) != write(fd,&value,sizeof(int))) //将值写入文件,有异常则关闭文件并且退出
    {
      printf("write error on:%s\n",fn);
      close(fd);
      return res;
    }
    close(fd); //关闭文件
  }



  //part 2
  if(NULL == (dir=opendir(path))) //打开目录
  {
    printf("open dir error:%s\n",path);
    return res;
  }
  while(NULL != (de=readdir(dir))) //遍历目录中的每个条目
  {
    len=strlen(de->d_name); 
    if(de->d_name[0]=='f' && de->d_name[len-1]=='2' ) //如果文件名以f开头并且以2结尾
    {
      strcpy(fn,path);
      strcat(fn,"/");
      strcat(fn,de->d_name); //拼接出文件的全路径
      if(-1 == (fd=open(fn,O_RDONLY,0644))) //打开此文件
      {
	printf("cannot open file:%s\n",fn);
	return res;
      }
      value=0;
      if(sizeof(int) != read(fd,&value,sizeof(int))) //读出内容存到value变量中
      {
	printf("read error on:%s\n",fn);
	return res;
      }
      sum+=value; //将value中的值累加到sum中
      close(fd); //收尾操作
    }
  }
  printf("the sum is:%d\n",sum); //将结果输出

  

  //part 3
  rewinddir(dir); //重新定位目录指针到目录开始处
  while(NULL != (de=readdir(dir)))  //遍历目录中的每个条目
  {
    len=strlen(de->d_name);
    if( de->d_name[len-1]=='2' ) //如果文件名以2结尾
    {
      strcpy(fn,path);
      strcat(fn,"/");
      strcat(fn,de->d_name); //拼接出文件的全路径
      if(-1 == remove(fn)) //进行删除
      {
	printf("remove failed :%s\n",fn);
	return res;
      }
    }
  }

  closedir(dir);
  res=0;
  return 0;
}

编译执行

emacs@ubuntu:~/c$ alias gtc
alias gtc='gcc -Wall -g -o'
emacs@ubuntu:~/c$ gtc filedir.x filedir.c
emacs@ubuntu:~/c$ ./filedir.x 
the sum is:800
emacs@ubuntu:~/c$

编译执行过程中没有报错,从结果来看,符合预期


remove

remove 函数的原型可以在头文件 stdio.h 中找到

emacs@ubuntu:/usr/include$ grep -B 1  remove  stdio.h  
/* Remove file FILENAME.  */
extern int remove (__const char *__filename) __THROW;
emacs@ubuntu:/usr/include$ 

remove 接收一个文件名字符串,并将该文件删除


总结

以下这些函数可以应对绝大部分的文件或目录属性查询需求

  • opendir
  • closedir
  • readdir
  • rewinddir

通过各方面资料弄懂其参数的意义和返回值的类型,是熟练掌握的基础

原文地址 http://soft.dog/2017/01/04/c-filestat-02/

评论