原文地址:C语言中关于对目录的操作

目录的操作不论是在嵌入式产品还是应用软件编程都是必不可少的,不同的开发语言可能略有不同,笔者主要是讨论在Linux平台下对目录的一系列操作:

1、获取当前目录操作:

在系统命令行下我们可以直接输入命令:pwd 来获取当前的工作目录,但是你知道这个命令是怎么执行的吗?它是由系统通过 Shell 程序来解释执行的,在我们自己编写程序的时候怎么能获取当前的工作目录呢?在标准C库中提供了一系列关于目录操作的接口函数:

char * getcwd(char * buf,size_t size);

getcwd函数把当前目录的名字写到给定的缓冲区buf里。如果目录的名字超出了参数size给出的缓冲区长度(一个ERANGE错误),它就返回NULL。如果成功,它返回指针buf,我们可以访问buf来获取当前的目录。可能当你获取目录后可能需要进入这个目录或者跳到该目录的父目录,我们怎么操作呢?

2、  切换目录:

int chdir(const char *path);

就像我们在shell里使用cd命令来切换目录一样,在程序里则可以使用chdir系统调用来实现目录的变更,一般情况下是配合 Getcwd 函数一起使用来实现目录定位操作。

3、 目录的创建和删除:

在系统命令行下我们可以通过 “ mkdir” , “ rmdir” 命令通过Shell来实现帮我们创建一个目录和删除一个目录,如果在实际的产品开发中呢,总不可能我们自己去手动创建吧,很多情况下都是通过程序自动帮我们创建一个目录来存放相应的文件。系统I/O库中提供了下面相应的操作接口:

int mkdir(const char * path,mode_t mode);

mode的含义将按open系统调用的O_CREAT选项中的有关定义设置,当然,它还要服从umask的设置况。

int rmdir(const char *path);

4、 目录扫描:

对目录的扫描操作和文件的操作有点类似,都是通过对目录结构体的操作,这个结构是系统维护的,一般情况下用户不要去更改这个目录结构体中的相应字段:

struct dirent {
                   ino_t          d_ino;      
                   off_t          d_off;      
                   unsigned short d_reclen;   
                   unsigned char  d_type;     
                   char           d_name[256];
               };

通过这个结构我们可以方便的实现文件的过滤,通过访问结构体中的 “d_type” 和 “d_name” 变量可以非常方便的实现文件的查找,文件的访问,文件的过滤。要实现一系列的目录操作你总的先把这个目录打开吧:

打开目录:

DIR * opendir(const char *name)

函数返回一个目录结构指针,所以在使用该函数时,我们需要显示的定义相应的指针变量:

eg :   DIR *dpt;

读目录操作:

struct dirent *readdir(DIR *dir);

函数实现目录读操作,将目录流指针所指的目录读到相应的目录结构中,函数返回该结构的指针,所以我们在使用该接口之前我们需要显示的定于一个结构变量来接受函数的返回。

如:           struct dirent *dir;

dir = readdir(DIR *dpt);

在我们对目录的操作过程中你可能需要目录指针卷绕操作,在C标准库中也提供了相应的操作,和文件很相似吧 ,下面我们来看看:

void rewinddir(DIR *dir);

目录扫描:

int scandir(const char *dir,     struct dirent ***namelist,
                           int(*filter)(const struct dirent *),
              int(*compar)(const struct dirent **, const struct dirent **));

int alphasort(const void *a, const void *b);
             int versionsort(const void *a, const void *b);

咋一眼看到这个函数,复杂吧? 可能你在想我自己写个目录扫描小程序还简单呢?后面我们将提供一个这样小程序代码,我们先看这个函数的使用吧:

参数: const char *dir   ----------------------------------> 要扫描的目录指针

struct dirent ***namelist ------------------------->要扫描的目录结构

int(*filter)(const struct dirent *) -------------->要过滤的条件

int(*compar)(const struct dirent **, const struct dirent **));

---------------------------------->  扫描过程中要到的排序算法

下面是Linux系统自带的一个使用例子可以帮我理解该函数的使用:

#include <dirent.h>
int main(void) {
struct dirent **namelist;
int n; n = scandir(".", &namelist, , alphasort);
if (n < )
perror("scandir");
else {
while(n--) {
printf("%sn", namelist[n]->d_name);
free(namelist[n]);
}
free(namelist);
} return ;
} 例2: 自己实现一个目录扫描操作: #include <sys/types.h>
#include <dirent.h> #include <sys/stat.h>
#include <unistd.h> #include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h> #define MAX_DIR_ENT 1024 typedef int(*qsort_compar)(const void *, const void *); int hxy_scandir(const char *dir, struct dirent ***namelist,
int(*filter)(const struct dirent *),
int(*compar)(const struct dirent **, const struct dirent **))
{
DIR * od;
int n = ;
struct dirent ** list = NULL;
struct dirent * ent ,* p; if((dir == NULL) || (namelist == NULL))
return -; od = opendir(dir);
if(od == NULL)
return -; list = (struct dirent **)malloc(MAX_DIR_ENT*sizeof(struct dirent *)); while(( ent = readdir(od)) != NULL)
{
if(filter!=NULL && !filter(ent))
continue; p = (struct dirent *)malloc(sizeof(struct dirent)); memcpy((void *)p,(void *)ent,sizeof(struct dirent));
list[n] = p; n++;
if(n >= MAX_DIR_ENT)
break; } closedir(od); *namelist = realloc((void *)list,n*sizeof(struct dirent *));
if(*namelist == NULL)
*namelist = list; if(compar)
qsort((void *)*namelist,n,sizeof(struct dirent *),(qsort_compar)compar); return n; } int filter_fn(const struct dirent * ent)
{
if(ent->d_type != DT_REG)
return ; return (strncmp(ent->d_name,"lib",) == );
} typedef int(*scandir_compar)(const struct dirent **, const struct dirent **); //第二个版本的扫描目录程序,
void scan_lib(const char * dir_name)
{
int n;
struct dirent **namelist; n = hxy_scandir(dir_name, &namelist, filter_fn, (scandir_compar)alphasort);
if (n < )
perror("scandir");
else {
while(n--) {
printf("%sn", namelist[n]->d_name);
free(namelist[n]);
}
free(namelist);
} } int main(void)
{
scan_lib("/usr/lib");
return ; } 例3: #include <sys/types.h>
#include <dirent.h>
#include <string.h>
#include <stdio.h> int scan_file(char *dir_name)
{
DIR *dir;
struct dirent *ent;
char *ptr; dir = opendir(dir_name); if(dir == NULL)
{
fprintf(stderr,"open directory %s n",dir_name);
return -;
}
while( (ent = readdir(dir)) != NULL)
{ ptr = strrchr(ent->d_name,'.');
if(ptr && (strcasecmp(ent->d_name, ".txt") == )) printf("%sn", ent->d_name);
}
closedir(dir);
} int main(void)
{
scan_file("/root/Desktop/C/src");
}

5、目录关闭:

int closedir(DIR *dpt);

一些文件操作函数:http://blog.csdn.net/wh_19910525/article/details/13503221

         http://blog.csdn.net/simmerlee/article/details/8281399

C语言中关于对目录的操作的更多相关文章

  1. Objective-C:Objective-C:文件中一些对目录进行操作的函数

    IO文件中,一些对目录进行操作的函数:获取.切分.组合 一些对目录进行操作的函数: 获取用户的姓名:(NSString*)NSUserName() ;    ———>NSString *Str ...

  2. 在R语言中使用Stringr进行字符串操作

    今天来学习下R中字符串处理操作,主要是stringr包中的字符串处理函数的用法. 先导入stringr包,library(stringr),require(stringr),或者stringr::函数 ...

  3. Python中OS对目录的操作以及引用

    路径的获取 对当前目录的获取 1 path = os.getcwd() 2 print("获取到的当前目录是:({})".format(path)) 获取当前文件所在的绝对路径 i ...

  4. C语言中的函数

    C语言中的函数 目录 概述——对函数的理解 C语言中函数的定义和声明 函数允许的参数类型 函数允许的返回类型 递归 概述 由于有些代码段在编写程序的时候经常会用到,此时我们为了减少代码文件的长度和增加 ...

  5. JSON在各种语言中的运用

    1. JSON数据格式 JSON(JavaScript Object Notation) 从结构上看,所有的数据最终都可以分成三种类型:  第一种类型是scalar(标量),也就是一个单独的strin ...

  6. C语言中时钟编程

    目录 C语言中时钟编程 1. 文章目的 2.基本概念 2.1 UTC时间 2.2 UNIX纪元时间 2.3 格林威治时间 (GMT) 3.时间转换 3.1 asctime函数 3.2 ctime函数 ...

  7. PHP中目录的操作

    文件的操作:创建文件,删除文件,重命名文件rename(),移动/复制文件,读取,大小(PHP都有内置的函数) 目录的操作:创建目录(有),删除目录,复制目录,统计目录大小,遍历(自己定义函数) 一. ...

  8. c语言中文件相关操作

    一 .首先介绍一下数据文件的类型: 1.二进制文件(映像文件):在内存中以二进制形式存取. 2.文本文件(ascii文件):以ascii码形式存取的文件. 通俗的讲,在Mac下,你把一个文件丢进记事本 ...

  9. Android For JNI(二)——C语言中的数据类型,输出,输入函数以及操作内存地址,内存修改器

    Android For JNI(二)--C语言中的数据类型,输出,输入函数以及操作内存地址,内存修改器 当我们把Hello World写完之后,我们就可以迈入C的大门了,今天就来讲讲基本的一些数据类型 ...

随机推荐

  1. ElasticSearch配置说明

    配置文件位于%ES_HOME%/config/elasticsearch.yml文件中. cluster.name: elasticsearch 配置集群名称,默认elasticsearch node ...

  2. EF6 CodeFirst+Repository+Ninject+MVC4+EasyUI实践(五)

    前言 在编写代码的时候,我遇到了很多关于EntityFramework6的疑问,所以现在就提前把这些问题列出来做一下解答,以便在以后的代码编写过程中减少不必要的Bug. EntityFramework ...

  3. Understanding the Internal Message Buffers of Storm

    Understanding the Internal Message Buffers of Storm Jun 21st, 2013 Table of Contents Internal messag ...

  4. 使用ASP.NET上传图片汇总

    1 使用标准HTML来进行图片上传 前台代码: <body>      <form id="form1" runat="server"> ...

  5. ubuntu ulimit 设置

    永久设置ubuntu ulimit 之前是ulimit -n 65535那样设置,不过貌似只是当前环境有效果,重启服务器的话,又失效了...今天无意找到一个设置的方法,可以永久设置ulimit的参数. ...

  6. 1310. ACM Diagnostics

    http://acm.timus.ru/problem.aspx?space=1&num=1310 题目中说的 “the lexicographically increasing list” ...

  7. ICML历年Best Papers

    作者:我爱机器学习原文链接:ICML历年Best Papers ICML (Machine Learning)(1999-2016) 2016 Dueling Network Architecture ...

  8. android studio使用中遇到的问题

    旧版和新版切换会报错(点击更正, 不影响程序使用) 2.debug正常, 打包签名程序时候报错 String index out of range: -82 java.lang.StringIndex ...

  9. javamail 发送附件

    1.属性文件 mail.protocol=smtpmail.host=mail.port=mail.auth=truemail.timeout=25000mail.username=mail.pass ...

  10. c# 第一个实例 通哥

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...