Linux下目录编程(读取、创建、拷贝)

简介: 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 \*.

#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;
}


目录
相关文章
|
23天前
|
Linux
Linux中将文件解压到指定目录
Linux中将文件解压到指定目录
|
23小时前
|
Linux 程序员 开发者
源社区的兴起:从“代码隐士”到Linux引领的“全球编程嘉年华”
在编程的古老森林中,曾有“代码隐士”默默耕耘,惧怕智慧外泄。直到“开源”春风拂过,源社区如全球编程嘉年华盛开!开源文化颠覆了“独门秘籍”的传统,像“武林秘籍共享”般在网络上公开,鼓励知识传播与智慧碰撞。程序员组队开发,分享代码,提升科技实力。Linux则从“首席大厨”变身为“总导演”,以强大内核调制出诱人应用,引领潮流并推动技术创新。加入这场没有血腥厮杀,只有知识盛宴的“编程版《饥饿游戏》”吧!与全球开发者共享编程的乐趣与成就感!别忘了带上你的“独门秘籍”,可能下一个改变世界的创意就在其中!
12 5
|
3天前
|
存储 Linux Windows
Linux zip命令:压缩文件或目录
我们经常会在 Windows 系统上使用 “.zip”格式压缩文件,其实“.zip”格式文件是 Windows 和 Linux 系统都通用的压缩文件类型,属于几种主流的压缩格式(zip、rar等)之一,是一种相当简单的分别压缩每个文件的存储格式,本节要讲的 zip 命令,类似于 Windows 系统中的 winzip 压缩程序,其基本格式如下: [root@localhost ~]#zip [选项] 压缩包名 源文件或源目录列表 注意,zip 压缩命令需要手工指定压缩之后的压缩包名,注意写清楚扩展名,以便解压缩时使用。 下面给大家举几个例子。 【例 1】zip 命令的基本使用。 [r
18 0
Linux zip命令:压缩文件或目录
|
15天前
|
监控 Shell Linux
探索Linux操作系统下的Shell编程之魅力
【8月更文挑战第4天】本文旨在通过一系列精心设计的示例和分析,揭示在Linux环境下进行Shell编程的独特之处及其强大功能。我们将从基础语法入手,逐步深入到脚本的编写与执行,最终通过实际代码案例展现Shell编程在日常系统管理和自动化任务中的应用价值。文章不仅适合初学者构建扎实的基础,同时也为有一定经验的开发者提供进阶技巧。
28 11
|
15天前
|
Ubuntu Linux 开发工具
深入探索Linux内核模块编程
【8月更文挑战第4天】在这篇文章中,我们不仅将探讨Linux内核模块的基础知识,还将通过一个实际的例子来展示如何编写一个简单的内核模块。我们将从理论出发,逐步过渡到动手实践,最终实现一个可以在Linux系统上运行的模块。文章的目标是为读者提供足够的信息和知识,以便他们能够自己编写内核模块,从而对操作系统的内部工作原理有更深入的了解。
|
10天前
|
人工智能 Linux 索引
Linux专栏05:Linux基本指令之目录处理指令
Linux专栏05:Linux基本指令之目录处理指令
22 2
|
16天前
|
Linux
【Linux 或Mac系统】自动生成项目结构目录并放在README.md文件中
如何在Linux或Mac系统中使用tree命令自动生成项目结构目录,并将其格式化后放入项目的README.md文件中以展示项目结构。
35 1
|
17天前
|
安全 Linux Shell
Linux服务器 /etc/pam.d目录下的文件都是什么作用?
【8月更文挑战第2天】Linux服务器 /etc/pam.d目录下的文件都是什么作用?
40 2
|
22天前
|
Linux C语言 Windows
C语言文件编程-Linux环境下运行
本文介绍了在Linux环境下使用C语言进行文件编程时的两种主要接口:C标准库函数与Linux系统调用。C标准库提供了`fopen`, `fread`, `fwrite`, 和 `fclose`等函数,适用于普通文件操作;而Linux系统调用如`open`, `read`, `write`, 和 `close`则更适合处理设备文件,同时也可用于普通文件。这两种方法的主要区别在于前者使用文件指针,后者使用文件描述符。文章还给出了两个示例程序:一个使用C标准库函数实现文件复制,另一个则使用Linux系统调用完成相同任务。
19 2
|
5天前
|
Linux
Linux 查找进程所在目录
Linux 查找进程所在目录
15 0