linux c文件相关操作

扫描文件或文件夹的元数据,放入数组结构

/*
* brief: 扫描文件夹的所有文件或单文件元数据,放入pdir_metedata,如果是文件则pdir长度只有1
* param: parray传入外部空指针。 scan_dir传入文件夹路径。
* return: 返回true代表获取成功,否则失败。
*/
bool get_dir_metedata(GPtrArray** pdir_metedata, const pchar scan_dir, int* pstop_flag,
 PSCANING_INFO pscaning_info, const pchar prefix_path) 
{
    log_info(__FILE__, __LINE__, "get_dir_metedata begin dir :%s\n", scan_dir);

    struct stat filestat;

    char dir[MAX_PATH] = {0};

    uint ulen = strlen(scan_dir);

    memcpy(dir, scan_dir, ulen > MAX_PATH ? MAX_PATH : ulen);

    int ret = lstat(scan_dir, &filestat);

    if (ret == -1)
    {
        log_debug(__FILE__,__LINE__," get_dir_metedata(const pchar scan_dir){ ret = %d \n",ret);

        return false;
    }

    //*pdir_metedata = g_ptr_array_sized_new(1);
    *pdir_metedata = g_ptr_array_new_full(1, g_free);

    if (S_ISDIR(filestat.st_mode))
    {
        append_slash(dir);

        log_debug(__FILE__, __LINE__, "4 scan_dir : %s \n",dir);

        //uint ufiles_count = count_files(dir);

        get_parent_metedata(pdir_metedata, dir, pscaning_info, prefix_path);

        scan_folder_metedata(*pdir_metedata, dir, pstop_flag, pscaning_info);
    }
    else
    {
        get_parent_metedata(pdir_metedata, scan_dir, pscaning_info, prefix_path);
    }

    log_debug(__FILE__, __LINE__, " scan_dir %s files count:%d\n", dir, (*pdir_metedata)->len);

    log_debug(__FILE__, __LINE__, " get_dir_metedata(%s) is over\n", scan_dir);

    return true;
}

/*
* brief: 扫描指定路径,将文件元数据放入 pdir_metedata中
* param: path传入路径
*/
void scan_folder_metedata(GPtrArray* pdir_metedata, const pchar path,int *pstop_flag, PSCANING_INFO pscaning_info) 
{
    if (pscaning_info == NULL)
        log_info(__FILE__, __LINE__, " scan_folder_metedata pscaning_info is null, no product info");

    if (pstop_flag != NULL && *pstop_flag)
    {
        log_debug(__FILE__, __LINE__, " scan_folder_metedata stop through *pstop_flag");
        
        return;
    }
    
    if (!pdir_metedata)
    {
        log_error(__FILE__, __LINE__, " scan_folder pdir_metedata is null");

        return;
    }

    DIR *dir;
    struct dirent *entry;

    log_info(__FILE__, __LINE__, "scan_folder : %s\n", path);

    if (!(dir = opendir(path)))
    {
        log_error(__FILE__, __LINE__, "Cannot open directory: %s\n", path);

        return;
    }
    
    while ((entry = readdir(dir)) != NULL)
    {
        if (pstop_flag != NULL && *pstop_flag)
        {
            log_debug(__FILE__, __LINE__, " scan_folder_metedata while ((entry = readdir(dir)) != NULL) stop through *pstop_flag");
            
            return;
        }

        if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
            continue;

        log_info(__FILE__, __LINE__, "scan_folder  entry->d_name : %s\n", entry->d_name);

        PFILE_METEDATA pfile_metedata = malloc(sizeof(FILE_METEDATA));

        memset(pfile_metedata, 0, sizeof(FILE_METEDATA));

        char file_name[MAX_PATH] = {0};

        sprintf_s(file_name, MAX_PATH, "%s%s", path,entry->d_name);

        /*file_metedata->p_file_name = malloc(strlen(file_name) + 1);//+1是因为可能会补一下'/'符号
        memset(file_metedata->p_file_name, 0, strlen(file_name) + 1);*/

        struct stat stat_info;

        //memcpy(file_metedata->p_file_name, file_name, strlen(file_name));
        memcpy(pfile_metedata->file_name, file_name, strlen(file_name));

        int ret = lstat(pfile_metedata->file_name, &stat_info);
        
        if (ret != -1)
        {
            pfile_metedata->file_stat = stat_info;

            if (pscaning_info)
            {
                pscaning_info->utotal_size += pfile_metedata->file_stat.st_size;

                pscaning_info->ufile_counts++;

                log_debug(__FILE__, __LINE__, "scan_folder cursize:%u totalsize:%u file_counts:%u", 
                pfile_metedata->file_stat.st_size, pscaning_info->utotal_size, pscaning_info->ufile_counts);
            }

            if (S_ISDIR(stat_info.st_mode))
            {
                append_slash(pfile_metedata->file_name);

                pfile_metedata->cfile_type = ZTYPE_IS_DIR;

                log_debug(__FILE__, __LINE__, "scan_folder Directory: %s\n", pfile_metedata->file_name);

                g_ptr_array_add(pdir_metedata, (gpointer)pfile_metedata);

                scan_folder_metedata(pdir_metedata, pfile_metedata->file_name, pstop_flag, pscaning_info);
            }
            else
            {
                if (S_ISBLK(stat_info.st_mode))
                    pfile_metedata->cfile_type = ZTYPE_IS_BLOCK_DEV;
                else if(S_ISCHR(stat_info.st_mode))
                    pfile_metedata->cfile_type = ZTYPE_IS_C_DEV;
                else if (S_ISLNK(stat_info.st_mode))
                    pfile_metedata->cfile_type = ZTYPE_IS_LINK;
                else if (S_ISFIFO(stat_info.st_mode))
                    pfile_metedata->cfile_type = ZTYPE_IS_FIFO;
                else if (S_ISSOCK(stat_info.st_mode))
                    pfile_metedata->cfile_type = ZTYPE_IS_SOCK;    
                else
                    pfile_metedata->cfile_type = ZTYPE_IS_FILE;
                
                //char pmd5[MD5_LENGTH] = {0};
                
                //get_file_md5sum(pfile_metedata->file_name, pmd5);

                //md5_to_half(pmd5, pfile_metedata->file_md5);

                //log_debug(__FILE__, __LINE__, "scan_folder File: %s md5:%s half_md5:%u\n"
                //, pfile_metedata->file_name, pmd5, pfile_metedata->file_md5);

                log_debug(__FILE__, __LINE__, "scan_folder File: %s\n", pfile_metedata->file_name);

                g_ptr_array_add(pdir_metedata, (gpointer)pfile_metedata);
            }
        }
        else
            log_error(__FILE__, __LINE__, " stat filename = %s is error", pfile_metedata->file_name);

        log_info(__FILE__,__LINE__,"scan_folder  file_metedata->file_name : %s\n", pfile_metedata->file_name);
    }

    closedir(dir);
}

/*
* brief: 将文件或目录的filestat属性 加入 pdir_metedata数组。
* param: pdir_metedata 返回的ptr数组,scan_dir 目录或文件,pscaning_info 扫描过程中产生的数据,filestat 外部已经获得的filestat
*/
void add_to_ptrarray(GPtrArray** pdir_metedata, const pchar scan_dir, PSCANING_INFO pscaning_info, struct stat* filestat)
{       
    PFILE_METEDATA pfile_metedata = malloc(sizeof(FILE_METEDATA));

    memset(pfile_metedata, 0, sizeof(FILE_METEDATA));

    memcpy(pfile_metedata->file_name, scan_dir, strlen(scan_dir));

    pfile_metedata->file_stat = *filestat;

    if (S_ISBLK(filestat->st_mode))
        pfile_metedata->cfile_type = ZTYPE_IS_BLOCK_DEV;
    else if(S_ISCHR(filestat->st_mode))
        pfile_metedata->cfile_type = ZTYPE_IS_C_DEV;
    else if (S_ISLNK(filestat->st_mode))
        pfile_metedata->cfile_type = ZTYPE_IS_LINK;
    else if (S_ISDIR(filestat->st_mode))
        pfile_metedata->cfile_type = ZTYPE_IS_DIR;
    else if (S_ISSOCK(filestat->st_mode))
        pfile_metedata->cfile_type = ZTYPE_IS_SOCK;
    else if (S_ISFIFO(filestat->st_mode))
        pfile_metedata->cfile_type = ZTYPE_IS_FIFO; 
    else
        pfile_metedata->cfile_type = ZTYPE_IS_FILE;

    if (pscaning_info)
    {
        pscaning_info->utotal_size += pfile_metedata->file_stat.st_size;

        pscaning_info->ufile_counts++;

        log_debug(__FILE__, __LINE__, "get_dir_metedata  cursize:%u totalsize:%u", 
        pfile_metedata->file_stat.st_size, pscaning_info->utotal_size);
    }

    g_ptr_array_add(*pdir_metedata, (gpointer)pfile_metedata);
}


/*
* brief: 获取所有父目录的metedata,除了/。该方法不提供外部使用,需要的话自行封一个
* param: pdir_metedata 返回的ptr数组,scan_dir 目录或文件,pscaning_info 扫描过程中产生的数据
*/
void get_parent_metedata(GPtrArray** pdir_metedata, const pchar scan_dir, PSCANING_INFO pscaning_info, const pchar prefix_path)
{
    struct stat st;
    char parent[MAX_PATH] = {0};

    strcpy(parent, scan_dir);
    
    char prefix_temp[MAX_PATH] = {0};

    if (prefix_path)
        strcpy(prefix_temp, prefix_path);

    // 反复直到到达根目录
    while (lstat(parent, &st) != -1 && st.st_ino != 2 && (strcmp(parent, "/") != 0 && strcmp(parent, prefix_temp) != 0))
    {
        add_to_ptrarray(pdir_metedata, parent, pscaning_info, &st);
        // 获取上一级目录
        char tmp[MAX_PATH] = {0};
        strcpy(tmp, dirname(parent));
        strcpy(parent, tmp);

        append_slash(parent);
    }
}

/*
* brief: 扫描文件的元数据,放入pdir_metedata
* param: file_name传入文件路径,pfile_metedata由外部申请,是一个回参
* return: 返回true代表获取成功,否则失败。
*/
bool get_file_metedata(const pchar file_name, PFILE_METEDATA pfile_metedata, bool is_md5)
{
    log_debug(__FILE__, __LINE__, "%s\n", file_name);

    struct stat filestat;

    int ret = lstat(file_name, &filestat);

    if (ret == -1)
    {
        log_debug(__FILE__,__LINE__," stat(file_name, &filestat); ret = %d,%s\n",ret, strerror(errno));

        return false;
    }

    strcpy_s(pfile_metedata->file_name, MAX_PATH, file_name);

    pfile_metedata->file_stat = filestat;

    if (S_ISDIR(filestat.st_mode))
        pfile_metedata->cfile_type = ZTYPE_IS_DIR;
    else if (S_ISBLK(filestat.st_mode))
        pfile_metedata->cfile_type = ZTYPE_IS_BLOCK_DEV;
    else if(S_ISCHR(filestat.st_mode))
        pfile_metedata->cfile_type = ZTYPE_IS_C_DEV;
    else if (S_ISLNK(filestat.st_mode))
        pfile_metedata->cfile_type = ZTYPE_IS_LINK;
    else if (S_ISSOCK(filestat.st_mode))
        pfile_metedata->cfile_type = ZTYPE_IS_SOCK;
    else if (S_ISFIFO(filestat.st_mode))
        pfile_metedata->cfile_type = ZTYPE_IS_FIFO; 
    else
        pfile_metedata->cfile_type = ZTYPE_IS_FILE;

    if(is_md5 == true)
    {
        /*
        char pmd5[MD5_LENGTH] = {0};
                
        get_file_md5sum(pfile_metedata->file_name, pmd5);

        md5_to_half(pmd5, pfile_metedata->file_md5);

        log_debug(__FILE__, __LINE__, "scan_folder File: %s md5:%s half_md5:%u"
                , pfile_metedata->file_name, pmd5, pfile_metedata->file_md5);
        */
        char a_md5[MD5_MIN_SIZE * 2 + 1] = {0};
        //calculate_file_md5(pfile_metedata->file_name, pfile_metedata->file_md5);
        boost_get_md5(g_hash_table, pfile_metedata, "get_file_metedata");
        get_md5_format(&pfile_metedata->file_md5, a_md5);
        log_debug(__FILE__, __LINE__, "scan_folder File: %s md5:%s" , pfile_metedata->file_name, a_md5);
    }
    else
    {
    //char* pmd5 = md5minto32(file_metedata->file_md5);
        log_debug(__FILE__, __LINE__, "scan_folder File: %s", pfile_metedata->file_name);
    }
    
    return true;
}

以上内容包含了glib 的数据结构、md5的计算方式,可自行替换。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值