Linux下目录编程(读取、创建、拷贝)
2021/12/5 7:18:01
本文主要是介绍Linux下目录编程(读取、创建、拷贝),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
一、前言
之前有几篇文章介绍了Linux下文件编程,那么目录和文件编程类似,也有一套函数,可以打开,读取、创建目录等。创建目录、文件除了命令以外(mkdir、touch
),都有对应的函数实现相同功能。
使用较多的就是遍历目录的功能,比如: 音乐播放器需要循环播放指定目录下所有音频文件,视频播放器需要遍历指定目录查找所有的视频文件加入到播放列表等等。
目录操作相关函数如下:
#include <sys/types.h> #include <dirent.h> DIR *opendir(const char *name); 函数功能: 打开目录 函数形参: const char *name :打开的目录路径 返回值: 目录打开成功返回指向该目录的指针. struct dirent *readdir(DIR *dirp); 函数功能: 读目录. 每调用一次就获取一次当前目录下一个文件的信息. 函数形参: DIR *dirp :打开的目录指针. 返回值:保存当前读取成功的文件信息. 该函数可以重复调用,调用成功就返回当前目录下一个文件的信息,如果读取失败或者文件读取完毕返回NULL。 struct dirent { ino_t d_ino; /* inode number */ off_t d_off; /* offset to the next dirent */ unsigned short d_reclen; /* length of this record */ unsigned char d_type; /* type of file; not supported by all file system types */ char d_name[256]; /* filename */ }; int closedir(DIR *dirp); 函数功能: 关闭已经打开的目录. #include <sys/stat.h> #include <sys/types.h> int mkdir(const char *pathname, mode_t mode); 函数功能: 创建一个新目录.
二、案例代码
2.1 遍历指定目录: 实现ls -a命令功能
#include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <dirent.h> int main(int argc,char **argv) { if(argc!=2) { printf("参数: ./a.out <目录的路径>\n"); return 0; } /*1. 打开目录*/ DIR *dir=opendir(argv[1]); if(dir==NULL) { printf("%s 目录打开失败.\n",argv[1]); return -1; } /*2. 遍历目录*/ struct dirent *dir_info; while(dir_info=readdir(dir)) { printf("%s ",dir_info->d_name); } printf("\n"); /*3. 关闭目录*/ closedir(dir); return 0; }
2.2 创建目录
#include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <dirent.h> #include <stdlib.h> int main(int argc,char **argv) { if(argc!=2) { printf("参数: ./a.out <创建的新目录名称>\n"); return 0; } printf("即将创建的新目录名称:%s\n",argv[1]); /*1. 调用mkdir函数创建目录*/ // printf("mkdir函数状态:%d\n",mkdir(argv[1],S_IWUSR|S_IRUSR)); // 成功返回为0 失败返回-1 ,该函数不能创建多层目录 /*2. 使用system函数调用系统命令完成目录的创建*/ char cmd_buf[100]; sprintf(cmd_buf,"mkdir %s -p",argv[1]); system(cmd_buf); return 0; }
2.3 得到文件和目录的名称
#include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <dirent.h> #include <stdlib.h> #include <libgen.h> int main(int argc,char **argv) { if(argc!=2) { printf("参数: ./a.out <路径>\n"); return 0; } //printf("目录名称:%s\n",dirname(argv[1])); //传入: /123/456/789/a.c 返回/123/456/789 printf("文件名称:%s\n",basename(argv[1])); //传入: /123/456/789/a.c 返回a.c return 0; }
2.4 命令行*.c传参的问题
#include <stdio.h> int main(int argc,char **argv) { int i; for(i=0;i<argc;i++) printf("%s\n",argv[i]); return 0; } [wbyq@wbyq linux_c]$ ./a.out *.c ./a.out 123.c 456.c app.c [wbyq@wbyq linux_c]$ ./a.out \*.c ./a.out *.c [wbyq@wbyq linux_c]$
2.5 使用目录操作函数实现ls *.c
使用目录操作函数实现ls *.c 或者ls *.mp3 类似的功能.
*号是特殊符号. 是通配符符号。./a.out \*.c
#include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <dirent.h> #include <string.h> #include <stdlib.h> int main(int argc,char **argv) { if(argc!=3) { printf("参数: ./a.out <目录的路径> <后缀例如:.c .mp3>\n"); return 0; } /*1. 打开目录*/ DIR *dir=opendir(argv[1]); if(dir==NULL) { printf("%s 目录打开失败.\n",argv[1]); return -1; } /*2. 遍历目录*/ struct dirent *dir_info; struct stat s_buf; //存放状态信息的 char *abs_path=NULL; while(dir_info=readdir(dir)) { if(strstr(dir_info->d_name,argv[2])) { //1. 申请空间 abs_path=malloc(strlen(argv[1])+strlen(dir_info->d_name)+1); //2. 拼接路径 sprintf(abs_path,"%s%s",argv[1],dir_info->d_name); printf("%s\n",abs_path); //3. 释放空间 free(abs_path); } } /*3. 关闭目录*/ closedir(dir); return 0; }
2.6 拷贝单层目录
实现cp命令的功能. 支持拷贝单层目录.
例如: cp 123.c 456.c 或者 cp abc/ work/ -a
#include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <dirent.h> #include <string.h> #include <stdlib.h> int cp_file(const char *src_file,const char *new_file); int main(int argc,char **argv) { if(argc!=3) { printf("参数: ./a.out <源目录的路径> <目标目录的路径>\n"); return 0; } /*1. 打开目录*/ DIR *dir=opendir(argv[1]); if(dir==NULL) { printf("%s 目录打开失败.\n",argv[1]); return -1; } /*2. 遍历目录*/ struct dirent *dir_info; struct stat s_buf; //存放状态信息的 char *abs_path=NULL; char *new_abs_path=NULL; while(dir_info=readdir(dir)) { //1. 申请空间 abs_path=malloc(strlen(argv[1])+strlen(dir_info->d_name)+1); //2. 拼接路径 sprintf(abs_path,"%s%s",argv[1],dir_info->d_name); //3.判断文件的类型 stat(abs_path,&s_buf); if(S_ISREG(s_buf.st_mode)) //普通文件 { new_abs_path=malloc(strlen(argv[2])+strlen(dir_info->d_name)+1); sprintf(new_abs_path,"%s%s",argv[2],dir_info->d_name); cp_file(abs_path,new_abs_path); free(new_abs_path); } //4. 释放空间 free(abs_path); } /*3. 关闭目录*/ closedir(dir); return 0; } /* 函数功能: 拷贝指定的文件 */ int cp_file(const char *src_file,const char *new_file) { /*1. 打开源文件*/ FILE *src_fp=fopen(src_file,"rb"); if(src_fp==NULL)return -1; /*2. 创建新文件*/ FILE *new_fp=fopen(new_file,"wb"); if(new_fp==NULL)return -2; /*3. 拷贝文件*/ unsigned char buff[1024]; int cnt; while(1) { cnt=fread(buff,1,1024,src_fp); fwrite(buff,1,cnt,new_fp); if(cnt!=1024)break; } /*4. 关闭文件*/ fclose(new_fp); fclose(src_fp); return 0; }
这篇关于Linux下目录编程(读取、创建、拷贝)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-12如何创建可引导的 ESXi USB 安装介质 (macOS, Linux, Windows)
- 2024-11-08linux的 vi编辑器中搜索关键字有哪些常用的命令和技巧?-icode9专业技术文章分享
- 2024-11-08在 Linux 的 vi 或 vim 编辑器中什么命令可以直接跳到文件的结尾?-icode9专业技术文章分享
- 2024-10-22原生鸿蒙操作系统HarmonyOS NEXT(HarmonyOS 5)正式发布
- 2024-10-18操作系统入门教程:新手必看的基本操作指南
- 2024-10-18初学者必看:操作系统入门全攻略
- 2024-10-17操作系统入门教程:轻松掌握操作系统基础知识
- 2024-09-11Linux部署Scrapy学习:入门级指南
- 2024-09-11Linux部署Scrapy:入门级指南
- 2024-08-21【Linux】分区向左扩容的方法