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


目录
相关文章
|
2月前
|
Linux
在 Linux 系统中,“cd”命令用于切换当前工作目录
在 Linux 系统中,“cd”命令用于切换当前工作目录。本文详细介绍了“cd”命令的基本用法和常见技巧,包括使用“.”、“..”、“~”、绝对路径和相对路径,以及快速切换到上一次工作目录等。此外,还探讨了高级技巧,如使用通配符、结合其他命令、在脚本中使用,以及实际应用案例,帮助读者提高工作效率。
109 3
|
2月前
|
存储 Linux Windows
linux常用目录
/sbin s就是super User的意思,这里存放的是系统管理员使用的系统管理程序。 /home 存放普通用户的主目录,在Linux中每个用户都有一个自己的目录,一版该目录名是以用户的账号命名的。 /root 该目录为系统管理员,也称为超级权限者的用户主目录。 /lib 系统开机所需要最基本的动态连接共享库,其作用类似于windows里的DLL文件。几乎所有的应用程序都需要用到这些共享库。 /etc 所有的系统管理所需要的配置文件和子目录。 /usr 这是一个非常重要的目录,用户的很多应用程序和文件都放在这个目录下,类似于windows下的program fies目录。 /bo
53 2
|
12天前
|
Linux
linux查看目录下的文件夹命令,find查找某个目录,但是不包括这个目录本身?
通过本文的介绍,您应该对如何在 Linux 系统中查看目录下的文件夹以及使用 `find` 命令查找特定目录内容并排除该目录本身有了清晰的理解。掌握这些命令和技巧,可以大大提高日常文件管理和查找操作的效率。 在实际应用中,灵活使用这些命令和参数,可以帮助您快速定位和管理文件和目录,满足各种复杂的文件系统操作需求。
33 8
|
21天前
|
存储 监控 Linux
嵌入式Linux系统编程 — 5.3 times、clock函数获取进程时间
在嵌入式Linux系统编程中,`times`和 `clock`函数是获取进程时间的两个重要工具。`times`函数提供了更详细的进程和子进程时间信息,而 `clock`函数则提供了更简单的处理器时间获取方法。根据具体需求选择合适的函数,可以更有效地进行性能分析和资源管理。通过本文的介绍,希望能帮助您更好地理解和使用这两个函数,提高嵌入式系统编程的效率和效果。
89 13
|
2月前
|
运维 监控 网络协议
运维工程师日常工作中最常用的20个Linux命令,涵盖文件操作、目录管理、权限设置、系统监控等方面
本文介绍了运维工程师日常工作中最常用的20个Linux命令,涵盖文件操作、目录管理、权限设置、系统监控等方面,旨在帮助读者提高工作效率。从基本的文件查看与编辑,到高级的网络配置与安全管理,这些命令是运维工作中的必备工具。
172 3
|
2月前
|
Linux Python
Linux 中某个目录中的文件数如何查看?这篇教程分分钟教会你!
在 Linux 系统中,了解目录下文件数量是常见的需求。本文介绍了四种方法:使用 `ls` 和 `wc` 组合、`find` 命令、`tree` 命令以及编程实现(如 Python)。每种方法都附有详细说明和示例,适合不同水平的用户学习和使用。掌握这些技巧,可以有效提升系统管理和日常使用的效率。
890 6
|
2月前
|
分布式计算 Java Hadoop
linux中HADOOP_HOME和JAVA_HOME删除后依然指向旧目录
通过以上步骤,可以有效地解决 `HADOOP_HOME`和 `JAVA_HOME`删除后依然指向旧目录的问题。确保在所有相关的配置文件中正确设置和删除环境变量,并刷新当前会话,使更改生效。通过这些措施,能够确保系统环境变量的正确性和一致性。
32 1
|
2月前
|
Linux Python
Linux 中某个目录中的文件数如何查看?这篇教程分分钟教会你!
在 Linux 系统中,了解目录下的文件数量是常见的需求。本文介绍了多种方法,包括使用 `ls` 和 `wc` 命令组合、`find` 命令、`tree` 命令以及编程方式(如 Python)。无论你是新手还是有经验的用户,都能找到适合自己的方法。掌握这些技巧将提高你在 Linux 系统中的操作效率。
85 4
|
2月前
|
网络协议 Linux
linux系统重要文件目录
本文介绍了Linux系统中的重要目录及其历史背景,包括根目录、/usr、/etc、/var/log和/proc等目录的结构和功能。其中,/etc目录下包含了许多关键配置文件,如网卡配置、DNS解析、主机名设置等。文章还详细解释了各目录和文件的作用,帮助读者更好地理解和管理Linux系统。
67 2
|
2月前
|
运维 监控 Shell
深入理解Linux系统下的Shell脚本编程
【10月更文挑战第24天】本文将深入浅出地介绍Linux系统中Shell脚本的基础知识和实用技巧,帮助读者从零开始学习编写Shell脚本。通过本文的学习,你将能够掌握Shell脚本的基本语法、变量使用、流程控制以及函数定义等核心概念,并学会如何将这些知识应用于实际问题解决中。文章还将展示几个实用的Shell脚本例子,以加深对知识点的理解和应用。无论你是运维人员还是软件开发者,这篇文章都将为你提供强大的Linux自动化工具。