Each encounter such a problem will always toss a long time, to search online, or check the information, get a lot of times, but it is not remember, this time to write the program has met, simply put it all clear, and then by the way here record, and later encountered will not have to look everywhere.
There are two main ways to traverse a directory file in C + +, respectively, in Windows VS environments and Linux\unix environments, each of which uses the following functions:
- (Windows VS) _findfirst, _findnext, _findclose
- (Linux\unix) Opendir, Readdir, Closedir
Let's talk about these two ways in detail.
First (_findfirst, _findnext, _findclose)
Basic Flow: _findfirst-->_findnext-->_findclose
(1) First Step
Function prototypes for _findfirst:
[CPP]View Plaincopy
- Long _findfirst ( char *filespec, struct _finddata_t *fileinfo);
It returns a file handle that can be used as an argument to other functions, and the file name matches the information of the first file of the pattern specified by filespec in FileInfo. For example, I want to find the TXT file in a directory, then FileInfo saved the first TXT file in this directory information, in which case we can call this function:
[CPP]View Plaincopy
- Long pFile = long _findfirst ( "*.txt", FileInfo);
The FileInfo used to save the file information is a struct with a data type of _finddata_t, defined in the header file IO.H:
[CPP]View Plaincopy
- struct _finddata_t {
- unsigned attrib; / * File attributes * /
- time_t time_create; /* File creation time, 1 for FAT file systems */
- time_t time_access; /* File last accessed time-1 for FAT file systems */
- time_t Time_write; / * The last time the file was written * /
- _fsize_t size; / * File size * /
- Char Name[_max_fname]; / * Matching file name, not including directory, _max_fname defined in STDLIB.H as 256 bytes * /
- };
Where the file attributes can be the following values (instructions on MSDN):
_a_arch (archive)
Archive. Set whenever the file is changed, and cleared by the BACKUP command. value:0x20
_a_hidden (hidden files)
Hidden file. Not normally seen with the DIR command, unless The/ah option is used. Returns information about the normal files as well as the files with this attribute. value:0x02
_a_normal (normal file, no read and write restrictions)
Normal. File can is read or written to without restriction. value:0x00
_a_rdonly (read-only file)
Read-only. File cannot is opened for writing, and a file with the same name cannot is created. value:0x01
_a_subdir (subdirectory)
subdirectory. value:0x10
_a_system (System file)
System file. Not normally seen with the DIR command, unless the/a or/a:s option is used. value:0x04
(2) Second Step
We have read the information of the first file, then how to read the next one, it is time to _findnext, we also first look at its function prototype:
[CPP]View Plaincopy
- int _findnext ( long handle, struct _finddata_t *fileinfo);
This function call returns 0 if successful, otherwise returns-1. It stores the information for the next file name that matches the filespec files in FileInfo, handle is the handle returned when _findfirst is called. For example, in our case, to get the information of the next TXT file, we can call the function like this
[CPP]View Plaincopy
- _findnext (PFile, FileInfo);
So we keep calling _findnext until it returns-1 to traverse all txt files.
(3) Step three
function _findclose is to do some finishing work, close the file handle:
[CPP]View Plaincopy
- int _findclose ( long handle);
Similarly, handle is also the handle returned when calling _findfirst.
(4) Final
To summarize, iterate through the files specified in a directory (all files are denoted by *) and can be written like this:
[CPP]View Plaincopy
- #include <io.h>
- int main ()
- {
- struct _finddata_t fileinfo;
- long hfile;
- if (hfile = _findfirst ("*.txt", &fileinfo) = = =-1)
- return-1;
- else {
- Do {
- /*process file*/
- }while (_findnext (hfile,&file) ==0);
- }
- _findclose (hfile);
- return 0;
- }
Second (Opendir, Readdir, Closedir)
Basic Flow: Opendir-->readdir-->closedir
(1) Step One
Using these functions we need to include header files <sys/types.h> and <dirent.h>.
We want to read the file information in the directory, first to open the directory, that is, to call the function Opendir:
[CPP]View Plaincopy
- DIR *opendir (const char *pathname);
This function takes the path of the directory as a parameter, and if opened successfully, returns a pointer of type DIR, equivalent to the above mentioned handle, for subsequent function calls, otherwise NULL is returned. So if you want to open the current directory you can call a function like this:
[CPP]View Plaincopy
- DIR *pdir = Opendir (".");
So we open the directory, and the return value pdir the arguments for the next function call.
(2) Step
Next is to read the information of the file, in <dirent.h> defined a structure dirent, used to save the file information, defined as follows:
[CPP]View Plaincopy
- struct Dirent {
- ino_t D_ino; / * I-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 * /
- Char d_name[256]; / * null-terminated filename * /
- };
What is often used in this is the D_type and D_name fields, respectively, representing the file type and file name.
D_type represents a file type, and its value is defined as follows:
[CPP]View Plaincopy
- Enum
- {
- Dt_unknown = 0,
- # define Dt_unknown Dt_unknown
- Dt_fifo = 1,
- # define DT_FIFO Dt_fifo
- DT_CHR = 2,
- # define DT_CHR DT_CHR
- Dt_dir = 4,
- # define Dt_dir Dt_dir
- DT_BLK = 6,
- # define DT_BLK dt_blk
- Dt_reg = 8,
- # define Dt_reg Dt_reg
- Dt_lnk = 10,
- # define Dt_lnk Dt_lnk
- Dt_sock = 12,
- # define Dt_sock Dt_sock
- DT_WHT = 14
- # define DT_WHT DT_WHT
- };
Then use the Readdir function to read the file information:
[CPP]View Plaincopy
- struct Dirent *readdir (DIR *DP);
DP is the return value when calling Opendir. When the read succeeds, the function returns a dirent struct pointer that holds the file information, returning NULL when the end of the directory is reached or when an error occurs. Each time the function is called to read the information of a file, the function is constantly called until it returns NULL, so that it can traverse all the files in that directory:
[CPP]View Plaincopy
- struct Dirent * ptr = Readdir (pdir);
(3) Step three
This last step is also the finishing touches, closing the directory:
[CPP]View Plaincopy
- int Closedir (DIR *DP);
Similarly, DP is the return value when calling Opendir, returns 0 on success, and 1 on failure.
[CPP]View Plaincopy
- Closedir (Pdir);
(4) Final
Therefore, the total traversal directory file of the program can be written like this:
[CPP]View Plaincopy
- #include <stdio.h>
- #include <sys/types.h>
- #include <dirent.h>
- int main ()
- {
- dir* Pdir;
- struct dirent* ptr;
- if (! ( dir = Opendir (".")))
- return-1;
- While (ptr = Readdir (pdir))! = 0)
- {
- /*processing file*/
- }
- Closedir (Pdir);
- return 0;
- }
Summarize
In general, the first method can only be used in Windows VS environments, while the second method can only be used in a linux/unix environment. Because in the process of using VS write a program to see if you can use the second method, the result is not to find the head file <dirent.h>, and from the definition of struct dirent we can see that it can only be used under Linux, because dirent There is a field in the definition that represents the I-node number of the file, which is exactly what is in the Linux file management. When you want to use the second method of Linux, you will not find the header file <io.h>. But there may be some methods on the network can be used in the two methods on two platforms, this I did not go to search the relevant information, if you have any good way, you can share. I've already tested all two of these programs, using VS2012 and Ubuntu.
In addition, the above explanation can be seen, under Windows can easily read the information of a certain type of file (such as TXT file), but under Linux it takes a bit more effort (such as to view the TXT file, you have to read the file information and then determine whether the file extension is a. txt).
C + + Traverse directory file, default directory