C语言中关于对目录的操作
原文地址: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语言中关于对目录的操作的更多相关文章
- Objective-C:Objective-C:文件中一些对目录进行操作的函数
IO文件中,一些对目录进行操作的函数:获取.切分.组合 一些对目录进行操作的函数: 获取用户的姓名:(NSString*)NSUserName() ; ———>NSString *Str ...
- 在R语言中使用Stringr进行字符串操作
今天来学习下R中字符串处理操作,主要是stringr包中的字符串处理函数的用法. 先导入stringr包,library(stringr),require(stringr),或者stringr::函数 ...
- Python中OS对目录的操作以及引用
路径的获取 对当前目录的获取 1 path = os.getcwd() 2 print("获取到的当前目录是:({})".format(path)) 获取当前文件所在的绝对路径 i ...
- C语言中的函数
C语言中的函数 目录 概述——对函数的理解 C语言中函数的定义和声明 函数允许的参数类型 函数允许的返回类型 递归 概述 由于有些代码段在编写程序的时候经常会用到,此时我们为了减少代码文件的长度和增加 ...
- JSON在各种语言中的运用
1. JSON数据格式 JSON(JavaScript Object Notation) 从结构上看,所有的数据最终都可以分成三种类型: 第一种类型是scalar(标量),也就是一个单独的strin ...
- C语言中时钟编程
目录 C语言中时钟编程 1. 文章目的 2.基本概念 2.1 UTC时间 2.2 UNIX纪元时间 2.3 格林威治时间 (GMT) 3.时间转换 3.1 asctime函数 3.2 ctime函数 ...
- PHP中目录的操作
文件的操作:创建文件,删除文件,重命名文件rename(),移动/复制文件,读取,大小(PHP都有内置的函数) 目录的操作:创建目录(有),删除目录,复制目录,统计目录大小,遍历(自己定义函数) 一. ...
- c语言中文件相关操作
一 .首先介绍一下数据文件的类型: 1.二进制文件(映像文件):在内存中以二进制形式存取. 2.文本文件(ascii文件):以ascii码形式存取的文件. 通俗的讲,在Mac下,你把一个文件丢进记事本 ...
- Android For JNI(二)——C语言中的数据类型,输出,输入函数以及操作内存地址,内存修改器
Android For JNI(二)--C语言中的数据类型,输出,输入函数以及操作内存地址,内存修改器 当我们把Hello World写完之后,我们就可以迈入C的大门了,今天就来讲讲基本的一些数据类型 ...
随机推荐
- Sql Server Alter语句
1:向表中添加字段 Alter table [表名] add [列名] 类型 2: 删除字段 Alter table [表名] drop column [列名] 3: 修改表中字段类型 (可以修 ...
- 常用doc命令
1.查看ip:ipconfig 2.ping命令 -t 就会一直ping,使用Ctrl+c退出 3.查看路由:route print 4.如何查看端口号被占用:netstat -aon| ...
- 基于事件的异步模式(EAP)
什么是EAP异步编程模式 EAP基于事件的异步模式是.net 2.0提出来的,实现了基于事件的异步模式的类将具有一个或者多个以Async为后缀的方法和对应的Completed事件,并且这些类都支持异步 ...
- DynamicJson
json字符串解析成Dynamic对象,开源地址http://dynamicjson.codeplex.com/,访问比较慢.使用方法摘录如下: Project Descriptiondynamic ...
- HttpServletResponse常用的方法
所有Servlet响应都实现ServletResponse接口.ServletResponse接口主要有以下方法: (1)从Servlet中可以通过getWriter方法取得PrintWriter对象 ...
- “如何稀释scroll事件”的思考(不小心写了个异步do...while)
看了下园友的一帖子:http://www.cnblogs.com/xzhang/p/4145697.html#commentform 本来以为是很简单的问题,但仔细想想还挺有意思的.简单的说就是增加事 ...
- 【初级】linux mkdir 命令详解及使用方法实战
mkdir命令详解及使用方法实战 名称 MKDIR 是 make directories 的缩写 使用方法 mkdir [选项(如-p)] ...目录名称(及子目录注意用分隔符隔开)... 如使 ...
- linux内核学习之一 简单c语言反汇编
(我是第一次发技术博客的菜鸟,恳请大家指导!!) 一 由简单c程序生成汇编代码 首先给出本次我们要反汇编的简单c语言程序:(够简单吧~) 在linux环境中使用下面的命令条件编译: 生成汇编文件sh ...
- android 加载中、无网络、无数据、出错 四种状态的代码封装
package com.weavey.loading.lib;import android.content.Context;import android.content.res.TypedArray; ...
- Dapper学习笔记(5)-存储过程
一.无参存储过程 第一步:创建一个不带参数的存储过程,代码如下: CREATE PROCEDURE [dbo].[QueryRoleNoParms] AS BEGIN SELECT * FROM T_ ...