分享

io.h下的_findfirst()和_finenext()

 kingwenguang 2015-06-17
一、这两个函数均在io.h里面。
二、首先了解一下一个文件结构体:
struct _finddata_t {
    unsigned    attrib;
    time_t      time_create;   
    time_t      time_access;   
    time_t      time_write;
    _fsize_t    size;
    char        name[260];
};

time_t,其实就是long
而_fsize_t,就是unsigned long

现在来解释一下结构体的数据成员吧。

attrib,就是所查找文件的属性:_A_ARCH(存档)、_A_HIDDEN(隐藏)、_A_NORMAL(正常)、_A_RDONLY(只读)、 _A_SUBDIR(文件夹)、_A_SYSTEM(系统)。

time_create、time_access和time_write分别是创建文件的时间、最后一次访问文件的时间和文件最后被修改的时间。

size:文件大小

name:文件名。

 
三、用 _findfirst 和 _findnext 查找文件

1、_findfirst函数:long _findfirst(const char *, struct _finddata_t *);

第一个参数为文件名,可以用"*.*"来查找所有文件,也可以用"*.cpp"来查找.cpp文件。第二个参数是_finddata_t结构体指针。若查找成功,返回文件句柄,若失败,返回-1。

 
2、_findnext函数:int _findnext(long, struct _finddata_t *);

第一个参数为文件句柄,第二个参数同样为_finddata_t结构体指针。若查找成功,返回0,失败返回-1。

3、_findclose()函数:int _findclose(long);

只有一个参数,文件句柄。若关闭成功返回0,失败返回-1。

 
四、查找文件例子

#include
#include
using namespace std;

int main()
{
 _finddata_t file;
 int k;
 long HANDLE;
 k = HANDLE = _findfirst( "*.*", &file );
 while( k != -1 )
 {
  cout << file.name << endl;
  k = _findnext( HANDLE, &file );
 }
 _findclose( HANDLE );

 return 0;
}

转自:http://blog.sina.com.cn/s/blog_67e046d10100jwdo.html


============================================================


_finddata_t

struct _finddata_t   是用来存储文件各种信息的结构体。定义如下:
struct _finddata_t
{
unsigned attrib;
time_t time_create;
time_t time_access;
time_t time_write;
_fsize_t size;
char name[_MAX_FNAME];
};
其中各成员变量的含义如下:
unsigned     attrib:
文件属性的存储位置。它存储一个unsigned单元,用于表示文件的属性。
文件属性是用位表示的,主要有以下一些:
_A_ARCH(存档)
_A_HIDDEN(隐藏)
_A_NORMAL(正常)
_A_RDONLY(只读)
_A_SUBDIR(文件夹)
_A_SYSTEM(系统)
这些都是在中定义的宏,可以直接使用,而本身的意义其实是一个无符号整型(只不过这个整型应该是2的几次幂,从而保证只有一位为1,而其他位为0)。既然是位表示,那么当一个文件有多个属性时,它往往是通过位或的方式,来得到几个属性的综合。例如只读+隐藏+系统属性,应该为:_A_HIDDEN | _A_RDONLY | _A_SYSTEM 。
time_t time_create:
这里的time_t是一个变量类型(长整型?相当于long int?),用来存储时间的,我们暂时不用理它,只要知道,这个time_create变量是用来存储文件创建时间的就可以了。
time_t time_access:文件最后一次被访问的时间。
time_t time_write:文件最后一次被修改的时间。
_fsize_t size:文件的大小。这里的_fsize_t应该可以相当于unsigned整型,表示文件的字节数。
char name[_MAX_FNAME]:文件的文件名。这里的_MAX_FNAME是一个常量宏,它在头文件中被定义,表示的是文件名的最大长度。
头文件引用: #include "io.h"


=========================================================

[转]C++下遍历文件夹

编写程序遍历文件夹及其子文件夹下所有文件,并输出到标准输出流或者文件流。 
1. 先考虑在单层目录下,遍历所有文件。以C:\WINDOWS为例: 
用到数据结构_finddata_t,文件信息结构体的指针。 

C++代码  
struct _finddata_t  
{  
    unsigned attrib;     //文件属性  
    time_t time_create;  //文件创建时间  
    time_t time_access;  //文件上一次访问时间  
    time_t time_write;   //文件上一次修改时间  
    _fsize_t size;  //文件字节数  
    char name[_MAX_FNAME]; //文件名  
};   


文件属性是无符号整数,取值为相应的宏:_A_ARCH(存档),_A_SUBDIR(文件夹),_A_HIDDEN(隐藏),_A_SYSTEM(系统),_A_NORMAL(正常),_A_RDONLY(只读)。容易看出,通过这个结构体,我们可以得到关于该文件的很多信息。结合以下函数,我们可以将文件信息存储到这个结构体中: 
C++代码  
//按FileName命名规则匹配当前目录第一个文件  
_findfirst(_In_ const char * FileName, _Out_ struct _finddata64i32_t * _FindData);   
 //按FileName命名规则匹配当前目录下一个文件  
_findnext(_In_ intptr_t _FindHandle, _Out_ struct _finddata64i32_t * _FindData);  
 //关闭_findfirst返回的文件句柄  
_findclose(_In_ intptr_t _FindHandle);  

_findfirst 函数返回的是匹配到文件的句柄,数据类型为long。遍历过程可以指定文件类型,这通过FileName的赋值来实现,例如要遍历C:\WINDOWS下的所有.exe文件 
C++代码  
bool transfer(string fileName = "C:\\Windows\\*.exe", int exeNum = 0)  
{  
    _finddata_t fileInfo;  
    long handle = _findfirst(fileName.c_str(), &fileInfo);  
  
    if (handle == -1L)  
    {  
        cerr << "failed to transfer files" << endl;  
        return false;  
    }  
  
    do   
    {  
        exeNum ++;  
        cout << fileInfo.name <
    } while (_findnext(handle, &fileInfo) == 0);  
    cout << " .exe files' number:  " << exeNum << endl;  
  
    return true;  
}  


2. 遍历文件夹及其子文件夹下所有文件。操作系统中文件夹目录是树状结构,使用深度搜索策略遍历所有文件。用到_A_SUBDIR属性,可运行程序如下: 
C++代码  
void dfsFolder(string folderPath, ofstream &fout)  
{  
    _finddata_t FileInfo;  
    string strfind = folderPath + "\\*";  
    long Handle = _findfirst(strfind.c_str(), &FileInfo);  
      
    if (Handle == -1L)  
    {  
        cerr << "can not match the folder path" << endl;  
        exit(-1);  
    }  
    do{  
        //判断是否有子目录  
        if (FileInfo.attrib & _A_SUBDIR)      
        {  
            //这个语句很重要  
            if( (strcmp(FileInfo.name,".") != 0 ) &&(strcmp(FileInfo.name,"..") != 0))     
            {  
                string newPath = folderPath + "\\" + FileInfo.name;  
                dfsFolder(newPath, fout);  
            }  
        }  
        else    
        {  
            fout << folderPath << "\\" << FileInfo.name  << " ";  
        }  
    }while (_findnext(Handle, &FileInfo) == 0);  
  
    _findclose(Handle);  
    fout.close();  
}  

在判断有无子目录的if分支中,由于系统在进入一个子目录时,匹配到的头两个文件(夹)是"."(当前目录),".."(上一层目录)。需要忽略掉这两种情况。当需要对遍历到的文件做处理时,在else分支中添加相应的代码就好

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多