Linux C/C++ 文件和目录操作

UNIX文件系统是目录和文件的一种结构。所有东西的起点是称为根的目录,这个目录的名称是一个字符“/”。

目录是一个包含项的文件。在逻辑上,可以认为每个目录项都包含一个文件名,同时还包含说明该文件属性的信息。那什么又是文件属性呢?文件属性是指文件的类型、文件大小、文件所有者等等。

我们要介绍的就是怎么列出一个目录的所有文件名字以及文件的大小。

opendir(打开目录)

opendir() 函数打开一个目录流(stream) ,参数是目录的路径, 返回指向这个目录的流指针。这个流指针指向打开目录的第一个记录项。

#include <sys/types.h>
#include <dirent.h>

DIR *opendir(const char *name); 

打开成功,返回指向目录流的指针;打开失败,则返回NULL,并设置相应的错误代码errno。

readdir(读取目录)

#include <sys/types.h>
#include <dirent.h>

struct dirent *readdir(DIR *dir); 

成功则返回下个目录进入点。有错误发生或读取到目录文件尾则返回NULL。

在Linux中, dirent structure的定义大致如下:

struct dirent {

    ino_t d_ino; /* inode number */

    off_t d_off; /* 到下一个dirent的偏移 */

    unsigned short d_reclen; /* 本记录项的长度 */

    unsigned char d_type; /* 文件的类型,不支持所有文件系统*/

    char d_name[256]; /* filename */

};

closedir(关闭目录)

closedir() 函数关闭一个目录流指针关联的目录。一次成功的调用closedir() 将闭底层的文件描述符与各种相关联。在此调用后,目录流描述符各种不可用。

#include <sys/types.h>
#include <dirent.h>

int closedir(DIR *dirp);

ls命令的简要实现

#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <time.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
	
	DIR *dp;

	struct dirent *dirp;

	if (argc != 2){
		printf("Usage:%s filename\n\a", argv[0]);
        exit(1);
	}

	if ((dp = opendir(argv[1])) == NULL){
		printf("Open Directory %s Error:%s\n",argv[1], strerror(errno));
        exit(1);
	}

	while((dirp = readdir(dp)) != NULL){
		printf("%s\n",dirp->d_name);
	}

	closedir(dp);

	return 0;
}

编译运行:

在这里插入图片描述

打印目录中各个文件的名字,不显示其他信息。这里要注意一下:我们使用opendir、readdir、closedir必须要包含一个系统文件 dirent.h

在Centos中,/usr/include/dirent.h 声明了函数原型。

获取目录下的文件大小

写一个例子,如果是一个目录我们输出这个目录下所有文件的大小。

#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdint.h>

int get_dir_size(char *dir_path, int64_t *dir_size)
{
    DIR *dir;
    struct dirent *dirp;
    char file_abs_path[256];
    struct stat buf;
    int64_t total_size_byte = 0;

    dir = opendir(dir_path);
    if(NULL == dir)
    {
        return 1;
    }

    while(NULL != (dirp = readdir(dir)))
    {
        
        if(DT_DIR == dirp->d_type)
        {
            printf("dir %s jump\n",dirp->d_name);
            continue;
        }

        /* file type */
        snprintf(file_abs_path,sizeof(file_abs_path),"%s/%s",dir_path,dirp->d_name);
        if(stat(file_abs_path,&buf))
        {
            printf("%s stat error.\n",file_abs_path);
            continue;
        }
        printf("%s file size %d\n",file_abs_path,buf.st_size);
        total_size_byte += buf.st_size;
    }

    *dir_size = total_size_byte;

    closedir(dir);

    return 0;
}
        
int main(int argc, char **argv){

    int ret = 0;
    int64_t dir_size;


    if (argc < 2){

        printf("Not input dir name\n");
        return -1;
    }

    ret = get_dir_size(argv[1],&dir_size);

    printf("dir_size %lld\n",dir_size);

    return 0;
}

编译输出:

在这里插入图片描述

总结

本篇介绍如果使用opendir、readdir、closedir对目录进行处理。使用opendir函数返回指向DIR结构的指针。DIR是在目录项格式头文件dirent.h中定义的,它表示一个目录流类型。

在循环中调用readdir来读每个目录项,它返回一个指向dirent结构的指针。在dirent结构中取出的只是每个目录项的名字。使用该名字,就可调用stat函数以获取该文件的所有属性。

参考:UNIX 环境高级编程。

需要【UNIX 环境高级编程】文件的,请添加本人微信号(17865354792),回复:UNIX

在这里插入图片描述

欢迎关注公众号【程序猿编码】,添加本人微信号(17865354792),回复:领取学习资料。或者回复:进入技术交流群。网盘资料有如下:

在这里插入图片描述

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Linux C/C中,可以使用inotify API来监控文件系统的事件。inotify API提供了一种异步的、高效的文件系统事件监控机制,可以监控文件目录的创建、删除、修改、移动等操作。 使用inotify API需要先创建一个inotify实例,并使用inotify_add_watch函数添加要监控的文件目录。当文件系统中发生对应的事件时,inotify会通知应用程序。 下面是一个简单的例子,演示如何使用inotify API监控文件变化: ```c #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/inotify.h> #define EVENT_SIZE ( sizeof (struct inotify_event) ) #define BUF_LEN ( 1024 * ( EVENT_SIZE + 16 ) ) int main( int argc, char **argv ) { int length, i = 0; int fd; int wd; char buffer[BUF_LEN]; fd = inotify_init(); if ( fd < 0 ) { perror( "inotify_init" ); } wd = inotify_add_watch( fd, "/tmp", IN_MODIFY | IN_CREATE | IN_DELETE ); while ( 1 ) { i = 0; length = read( fd, buffer, BUF_LEN ); if ( length < 0 ) { perror( "read" ); } while ( i < length ) { struct inotify_event *event = ( struct inotify_event * ) &buffer[ i ]; if ( event->len ) { if ( event->mask & IN_CREATE ) { if ( event->mask & IN_ISDIR ) { printf( "The directory %s was created.\n", event->name ); } else { printf( "The file %s was created.\n", event->name ); } } else if ( event->mask & IN_DELETE ) { if ( event->mask & IN_ISDIR ) { printf( "The directory %s was deleted.\n", event->name ); } else { printf( "The file %s was deleted.\n", event->name ); } } else if ( event->mask & IN_MODIFY ) { if ( event->mask & IN_ISDIR ) { printf( "The directory %s was modified.\n", event->name ); } else { printf( "The file %s was modified.\n", event->name ); } } } i += EVENT_SIZE + event->len; } } ( void ) inotify_rm_watch( fd, wd ); ( void ) close( fd ); exit( 0 ); } ``` 上面的代码中,先使用inotify_init函数创建一个inotify实例,然后使用inotify_add_watch函数添加要监控的目录。在while循环中,使用read函数读取inotify实例中的事件,然后根据事件类型进行相应的处理。最后使用inotify_rm_watch函数移除监控项,关闭inotify实例。 需要注意的是,inotify API只能用于Linux系统,其他操作系统需要使用不同的机制来监控文件系统事件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值