天天看点

#导入Word文档图片# Linux下目录编程

1.1 打开目录​

头文件​

#include <sys/types.h>

#include <dirent.h>

函数原型​

DIR *opendir(const char *name);

参数​

const char *name :目录的地址。

返回值​

成功返回一个指针指向的目录流。

执行错误,返回NULL。

1.2 关闭目录​

头文件​

#include <sys/types.h>

#include <dirent.h>

函数原型​

int closedir(DIR *dirp);

功能

关闭指定的目录。

返回值​

0表示成功,-1表示失败。

1.3 读取目录​

头文件​

#include <sys/types.h>

#include <dirent.h>

函数原型​

struct dirent *readdir(DIR *dirp);

int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result); //readdir的可重入版本

readdir函数返回值:失败返回空NULL。

readdir_r函数返回值:成功时返回0。错误时,它返回一个正的错误码。如果到达目录结尾,readdir_r() 返回0,并且把 *result 设置为 NULL。

相关结构体:

struct dirent {

ino_t d_ino; /* 节点号 */

off_t d_off; /* 偏移量 */

unsigned short d_reclen; /* 文件的长度*/

unsigned char d_type; /* 文件的类型*/

char d_name[256]; /* 文件名称 */

};

  • 遍历目录示例:

#include <sys/types.h>

#include <dirent.h>

#include <stdio.h>

#include <stdlib.h>

int main(int argc,char **argv)

{

if(argc!=2)

{

printf("error! usg: ./app dir");

exit(-1);

}

DIR *dirp=NULL;

dirp=opendir(argv[1]);

if(dirp==NULL)

{

printf("error!!\n");

exit(-1);

}

struct dirent *dir;

//循环遍历目录

while(dir=readdir(dirp))

{

printf("%s\n",dir->d_name); //打印文件的名称

}

closedir(dirp); //关闭目录

return 0;

}

1.4 设置读取的偏移量位置​

头文件​

#include <sys/types.h>

#include <dirent.h>

函数原型

void seekdir(DIR *dirp, long offset);

设置readfir函数的读取指针位置。

1.5 返回当前目录位置相对目录头的偏移量​

函数原型

#include <dirent.h>

long telldir(DIR *dirp);

获取当前目录指针的位置。相对目录头的偏移量。

  • 打印出文件目录的偏移位置:

#include <sys/types.h>

#include <dirent.h>

#include <stdio.h>

#include <stdlib.h>

int main(int argc,char **argv)

{

if(argc!=2)

{

printf("error! usg: ./app dir");

exit(-1);

}

DIR *dirp=NULL;

dirp=opendir(argv[1]);

if(dirp==NULL)

{

printf("error!!\n");

exit(-1);

}

struct dirent *dir;

long len;

//循环遍历目录

while(dir=readdir(dirp))

{

len=telldir(dirp);

printf("%s ",dir->d_name); //打印文件的名称

printf("%d\n",len);

}

return 0;

}

1.6 目录操作函数总汇​

1.6.1 获取目录信息相关的函数​

需要包含的头文件:

#include <sys/types.h>

#include <dirent.h>

相关的函数API:

DIR *opendir(const char *name);//打开一个目录

struct dirent *readdir(DIR *dir); //读取目录的一项信息,并返回该项信息的结构体指针

void rewinddir(DIR *dir);//重新定位到目录文件的头部

void seekdir(DIR *dir,off_t offset); //用来设置目录流目前的读取位置

off_t telldir(DIR *dir);//返回目录流当前的读取位置

int closedir(DIR *dir);//关闭目录文件

1.6.2 创建与删除目录相关的函数:​

需要包含的头文件:

#include <sys/stat.h>

#include <sys/types.h>

#include <unistd.h>

相关的函数API调用:

int mkdir(const char *pathname, mode_t mode);//创建目录,mode是目录权限。

int rmdir(const char *pathname);//删除目录。只能删除空目录

  • mkdir函数说明:mkdir()函数以mode方式创建一个以参数pathname命名的目录,mode定义新创建目录的权限。
  • 返回值:若目录创建成功,则返回0;否则返回-1
  • mode方式:
S_IRWXU 00700权限,代表该文件所有者拥有读,写和执行操作的权限
S_IRUSR(S_IREAD) 00400权限,代表该文件所有者拥有可读的权限
S_IWUSR(S_IWRITE) 00200权限,代表该文件所有者拥有可写的权限
S_IXUSR(S_IEXEC) 00100权限,代表该文件所有者拥有执行的权限
S_IRWXG 00070权限,代表该文件用户组拥有读,写和执行操作的权限
S_IRGRP 00040权限,代表该文件用户组拥有可读的权限
S_IWGRP 00020权限,代表该文件用户组拥有可写的权限
S_IXGRP 00010权限,代表该文件用户组拥有执行的权限
S_IRWXO 00007权限,代表其他用户拥有读,写和执行操作的权限
S_IROTH 00004权限,代表其他用户拥有可读的权限
S_IWOTH 00002权限,代表其他用户拥有可写的权限
S_IXOTH 00001权限,代表其他用户拥有执行的权限

注意:创建目录之前需要先调用umask函数。

该函数原型:

#include <sys/types.h>

#include <sys/stat.h>

mode_t umask(mode_t mask);

函数说明:

umask()会将系统umask值设成参数mask&0777后的值,然后将先前的umask值返回。在使用open()建立新文件时,该参数mode并非真正建立文件的权限,而是(mode&~umask)的权限值。

例如,在建立文件时指定文件权限为0666,通常umask值默认为022,则该文件的真正权限则为0666&~022=0644,也就是rw-r--r--返回值此调用不会有错误值返回。返回值为原先系统的umask值。

因此,创建目录之前,需要先执行umask(0) 然后再调用mkdir函数。

示例:

umask(0);

mkdir(argv[1],S_IRWXO);

1.6.3 改变文件的访问权限

#include <sys/stat.h>

int chmod(const char* path, mode_t mode);//mode形如:0777

path参数指定的文件被修改为具有mode参数给出的访问权限。

1.6.4 获取目录路径

原型为:

#include <unistd.h> //头文件

char *getcwd(char *buf, size_t size); //获取当前目录,相当于pwd命令

char *getwd(char *buf);

char *get_current_dir_name(void);

  • Getwd函数使用示例:

char *cwd;

cwd = getcwd (NULL, 0);

if (!cwd) {

perror (”getcwd”);

exit (EXIT_FAILURE);

}

printf (”cwd = %s\n”, cwd);

free (cwd);

char cwd[BUF_LEN];

if (!getcwd (cwd, BUF_LEN)) {

perror (”getcwd”);

exit (EXIT_FAILURE);

}

printf (”cwd = %s\n”, cwd);

  • get_current_dir_name函数使用示例:

char *cwd;

cwd = get_current_dir_name ( );

if (!cwd) {

perror (”get_current_dir_name”);

exit (EXIT_FAILURE);

}

printf (”cwd = %s\n”, cwd);

free (cwd);

  • getwd函数使用示例:

char cwd[PATH_MAX];

if (!getwd (cwd)) {

perror (”getwd”);

exit (EXIT_FAILURE);

}

printf (”cwd = %s\n”, cwd);

1.6.5 打开目录与读目录​

opendir函数打开目录;

readdir函数读取目录的内容,如果已经读取到目录末尾,又想重新开始读,则可以使用rewinddir函数将文件指针重新定位到目录文件的起始位置;

closedir函数关闭目录

1.6.6 改变目录路径​

#include <unistd.h>

int chdir(const char *path);

int fchdir(int fd);

Linux为改变当前目录,提供了两个函数,一个接受目录名,一个接受已经打开的目录文件描述符。

两个函数调用成功返回0,失败-1

注意: 这些改变目录的函数只是针对当前进程有效,Linux系统没有提供可以改变不同进程当前目录的机制。

  • 示例1:

char *swd;

int ret;

/* save the current working directory */

swd = getcwd (NULL, 0);

if (!swd) {

perror (”getcwd”);

exit (EXIT_FAILURE);

}

/* change to a different directory */

ret = chdir (some_other_dir);

if (ret) {

perror (”chdir”);

exit (EXIT_FAILURE);

}

/* do some other work in the new directory... */

/* return to the saved directory */

ret = chdir (swd);

if (ret) {

perror (”chdir”);

exit (EXIT_FAILURE);

}

free (swd);

  • 示例2:

int swd_fd;

swd_fd = open (”.”, O_RDONLY);

if (swd_fd == -1) {

perror (”open”);

exit (EXIT_FAILURE);

}

/* change to a different directory */

ret = chdir (some_other_dir);

if (ret) {

perror (”chdir”);

exit (EXIT_FAILURE);

}

/* do some other work in the new directory... */

/* return to the saved directory */

ret = fchdir (swd_fd);

if (ret) {

perror (”fchdir”);

exit (EXIT_FAILURE);

}

/* close the directory’s fd */

ret = close (swd_fd);

if (ret) {

perror (”close”);

exit (EXIT_FAILURE);

}

1.7 其他路径处理函数

1.7.1 获取目录名称

#include <stdio.h>

int main()

{

char *dirc, *basec, *bname, *dname;

char *path = "/etc/passwd";

dirc = strdup(path); //字符串拷贝函数,自带malloc空间申请

basec = strdup(path);

dname = dirname(dirc);

bname = basename(basec);

printf("dirname=%s, basename=%s\n", dname, bname);

return 0;

}

运行结果:

[root@wbyq test]# ./a.out

dirname=/etc, basename=passwd

该函数还有对应的命令:

[root@wbyq test]# dirname /work/123.c

/work

1.7.2 剔除目录名称

#include <libgen.h>

char *basename(char *path);

示例:

#include <stdio.h>

int main()

{

printf("%s\n",basename("/worok/123.c"));

return 0;

}

运行结果:

[root@wbyq test]# gcc 123.c

[root@wbyq test]# ./a.out

123.c

  • 该函数还有相对应的命令: basename

示例:

[root@wbyq test]# basename /work/123.c

123.c

  • 以上两个函数路径使用总结:

path dirname basename

"/usr/lib" "/usr" "lib"

"/usr/" "/" "usr"

"usr" "." "usr"

"/" "/" "/"

"." "." "."

".." "." ".."

1.7.3 字符串拷贝函数

#include <string.h>

char *strdup(const char *s);

char *strndup(const char *s, size_t n);

char *strdupa(const char *s);

char *strndupa(const char *s, size_t n);

功能: 将串拷贝到新建的位置处

strdup()在内部调用了malloc()为变量分配内存,不需要使用返回的字符串时,需要用free()释放相应的内存空间,否则会造成内存泄漏。

返回值:返回一个指针,指向为复制字符串分配的空间;如果分配空间失败,则返回NULL值。

示例:

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

int main()

{

char data[]="1234567890";

char *p=strdup(data);

printf("p=%s\n",p);

free(p);

return 0;