windows下类似linux readdir()读取文件

原创 2016年05月04日 11:02:29

仿写头文件 dirent.h

模拟linux下头文件 myDirent.h

#ifndef MYDIRENT_H
#define MYDIRENT_H

typedef struct _dirdesc {
    int     dd_fd;      /** file descriptor associated with directory */
    long    dd_loc;     /** offset in current buffer */
    long    dd_size;    /** amount of data returned by getdirentries */
    char    *dd_buf;    /** data buffer */
    int     dd_len;     /** size of data buffer */
    long    dd_seek;    /** magic cookie returned by getdirentries */
} DIR;

# define __dirfd(dp)    ((dp)->dd_fd)

DIR *opendir(const char *);
struct dirent *readdir(DIR *);
void rewinddir(DIR *);
int closedir(DIR *);

#include <sys/types.h>

struct dirent
{
    long d_ino;              /* inode number*/
    off_t d_off;             /* offset to this dirent*/
    unsigned short d_reclen; /* length of this d_name*/
    unsigned char d_type;    /* the type of d_name*/
    char d_name[1];          /* file name (null-terminated)*/
};

#endif

实现函数 cpp

windows下仿写opendir() readdir() closedir()
利用FindFirstFile() FindNextFile() 这两个windows函数

myDirent.cpp

#include <iostream>
#include <string>
#include <stdio.h>
#include <windows.h>

#include "myDirent.h"

static HANDLE hFind;

DIR *opendir(const char *name)
{
    DIR *dir;
    WIN32_FIND_DATA FindData;
    char namebuf[512];

    //int sprintf ( char * str, const char * format, ... ); Write formatted data to string
    sprintf(namebuf, "%s\\*.*", name);

    hFind = FindFirstFile(namebuf, &FindData);
    if (hFind == INVALID_HANDLE_VALUE)
    {
        printf("FindFirstFile failed (%d)\n", GetLastError());
        return 0;
    }

    dir = (DIR *)malloc(sizeof(DIR));
    if (!dir)
    {
        printf("DIR memory allocate fail\n");
        return 0;
    }

    memset(dir, 0, sizeof(DIR));
    dir->dd_fd = 0;   // simulate return  

    return dir;
}
struct dirent *readdir(DIR *d)
{
    int i;

    BOOL bf;
    WIN32_FIND_DATA FileData;
    if (!d)
    {
        return 0;
    }

    bf = FindNextFile(hFind, &FileData);
    //fail or end  
    if (!bf)
    {
        return 0;
    }

    struct dirent *dir = (struct dirent *)malloc(sizeof(struct dirent) + sizeof(FileData.cFileName));

    for (i = 0; i < 256; i++)
    {
        dir->d_name[i] = FileData.cFileName[i];
        if (FileData.cFileName[i] == '\0') break;
    }
    dir->d_reclen = i;
    dir->d_reclen = FileData.nFileSizeLow;

    //check there is file or directory  
    if (FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
    {
        dir->d_type = 2;
    }
    else
    {
        dir->d_type = 1;
    }

    return dir;
}
int closedir(DIR *d)
{
    if (!d) 
        return -1;
    hFind = 0;
    free(d);
    return 0;
}

测试一下

int main()
{
    // use as readdir() in Linux
    DIR *dir;
    struct dirent *ptr;

    char *flow[65536];
    int num = 0, i = 0;

    if ((dir = opendir("E:\\data_of_weibo\\data_washed\\event_max_time")) == NULL) {
        std::cerr << "open dir error." << std::endl;
        return false;
    }

    while ((ptr = readdir(dir)) != NULL) {
        flow[num] = (char *)malloc(sizeof(char));
        strcpy(flow[num], ptr->d_name);             //char d_name[1];
        num++;
    }

    // output test
    for (i = 0; i < num; ++i) {
        if (strcmp(flow[i], "..") == 0 || strcmp(flow[i], ".") == 0)
            std::cout << "find last directory." << std::endl;
        else
            std::cout << std::string(flow[i]) << std::endl;
    }
    std::cout << "total file: " << num - 1 << std::endl;

    closedir(dir);

    std::cout << "Press any key to continue.." << std::endl;
    getchar();

    return 0;
}

update:

//上面的写法,strcpy拷贝之后free flow数组会出问题,可能是覆盖了维护数据结构,改一下

int main()
{
    // use as readdir() in Linux
    DIR *dir;
    struct dirent *ptr;

    std::vector<std::string> resVec;

    int num = 0, i = 0;

    if ((dir = opendir("E:\\data_of_weibo\\data_washed\\event_max_time")) == NULL) {
        std::cerr << "open dir error." << std::endl;
        return false;
    }

    while ((ptr = readdir(dir)) != NULL)
        resVec.push_back(std::string(ptr->d_name));     //char d_name[1];

    for (unsigned j = 0; j < resVec.size(); j++)
        std::cout << resVec.at(j) << std::endl;     //包含 ".." 上级目录

    std::cout << resVec.size() << std::endl;

    closedir(dir);

    std::cout << "Press any key to continue.." << std::endl;
    getchar();

    return 0;
}

结果

注意结果里面有 “..” 上级目录,顺序是按照字母表顺序读取

这里写图片描述

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

给定A, B两个整数,不使用除法和取模运算,求A/B的商和余数

给定A, B两个整数,不使用除法和取模运算,求A/B的商和余数。 1.   最基本的算法是,从小到大遍历: for (i = 2 to A -1)          if (i * B > A)...

利用K-means聚类算法根据经纬度坐标对中国省市进行聚类

K-means聚类算法是一种非层次聚类算法,在最小误差的基础上将数据划分了特定的类,类间利用距离作为相似度指标,两个向量之间的距离越小,其相似度就越高。程序读取全国省市经纬度坐标,然后根据经纬度坐标进...

Radon变换理论介绍与matlab实现--经验交流

本人最近在研究Radon变换,在查阅了各种资料之后在此写下个人的理解,希望与各位牛牛进行交流共同进步,也使得理解更加深刻些。 Radon变换的本质是将原来的函数做了一个空间转换,即,将原来的XY平...

Matlab绘图-很详细,很全面

Matlab绘图强大的绘图功能是Matlab的特点之一,Matlab提供了一系列的绘图函数,用户不需要过多的考虑绘图的细节,只需要给出一些基本参数就能得到所需图形,这类函数称为高层绘图函数。此外,Ma...

CT图像重建技术

由于csdn贴图不方便,并且不能上传附件,我把原文上传到了资源空间CT图像重建技术 1.引言 计算机层析成像(Computed Tomography,CT)是通过对物体进行不同角度的射线投影测量而...

linux查找目录下的所有文件中是否含有某个字符串

查找目录下的所有文件中是否含有某个字符串  find .|xargs grep -ri "IBM"  查找目录下的所有文件中是否含有某个字符串,并且只打印出文件名  find .|xargs g...

Radon变换入门matlab CT原理

http://hi.baidu.com/hi9394/blog/item/0d492b8bfd714700c8fc7aa9.html 简介 图像投影,就是说将图像在某一方向上做线性积分(或理解为累...

Intel系列处理器的三种工作模式

Intel系列处理器的三种工作模式 微机中常用的Intel系列微处理器的主要发展过程是:8080,8086/8088,80186, 80286,80386,80486,Pentium,Pen...

js弹出框、对话框、提示框、弹窗总结

js弹出框、对话框、提示框、弹窗总结 一、JS的三种最常见的对话框 [javascript] view plaincopy //=...

form表单的两种提交方式,submit和button的用法

1.当输入用户名和密码为空的时候,需要判断。这时候就用到了校验用户名和密码,这个需要在jsp的前端页面写;有两种方法,一种是用submit提交。一种是用button提交。 方法一: 在jsp的...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:windows下类似linux readdir()读取文件
举报原因:
原因补充:

(最多只允许输入30个字)