Linux下目录编程(读取创建拷贝)
Posted DS小龙哥
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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下目录编程(读取创建拷贝)的主要内容,如果未能解决你的问题,请参考以下文章
防止代码拷贝,在Linux系统的PC,禁止数据拷贝方案,要求插U盘时能读取,但是不能拷贝东西到U盘。
Android 逆向使用 DB Browser 查看并修改 SQLite 数据库 ( 从 Android 应用数据目录中拷贝数据库文件 | 使用 DB Browser 工具查看数据块文件 )(代码片段
Android 逆向使用 DB Browser 查看并修改 SQLite 数据库 ( 从 Android 应用数据目录中拷贝数据库文件 | 使用 DB Browser 工具查看数据块文件 )(代码片段