C++遍历目录,并把目录里超过7天的文件删除(跨平台windows&linux)
C++遍历目录,并把目录里超过7天的文件删除,适用于项目里删除过期的日志,或者视频文件。
在windows和linux下测试通过。
windows测试结果:
linux测试结果:
源码:
1 #include <time.h> 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <string.h> 5 #include "dirent.h" 6 #include <sys/stat.h> 7 #include <errno.h> 8 #ifdef WIN32 9 10 #else 11 #include <unistd.h> 12 #endif 13 14 static int find_directory (const char *dirname); 15 16 17 int main(int argc, char *argv[]) 18 { 19 int i; 20 int result; 21 22 //循环遍历命令行里的每个目录 23 i = 1; 24 while (i < argc) { 25 result = find_directory (argv[i]); 26 if (result == -1) { 27 exit (EXIT_FAILURE); 28 } 29 i++; 30 } 31 32 //如果命令行参数为空,则遍历当前工作目录 33 if (argc == 1) { 34 find_directory ("."); 35 } 36 return EXIT_SUCCESS; 37 } 38 39 //删除7天前的文件 40 int RemoveFile( char* filename ) 41 { 42 int result; 43 //errno_t errno; 44 //获取文件信息 45 #ifdef WIN32 46 struct _stat buf; 47 result = _stat(filename, &buf); 48 #else 49 struct stat buf; 50 result = stat(filename, &buf); 51 #endif 52 53 if( result != 0 ) 54 { 55 perror( "Problem getting information" ); 56 switch (errno) 57 { 58 case ENOENT: 59 printf("File %s not found.\n", filename); 60 break; 61 case EINVAL: 62 printf("Invalid parameter to _stat.\n"); 63 break; 64 default: 65 /* Should never be reached. */ 66 printf("Unexpected error in _stat.\n"); 67 } 68 return -1; 69 } 70 else 71 { 72 // Output some of the statistics: 73 printf( "File size : %ld\n", buf.st_size ); 74 printf( "Drive : %c:\n", buf.st_dev + 'A' ); 75 76 time_t t; 77 tzset(); /*tzset()*/ 78 t = time(NULL); 79 if((t - buf.st_mtime) > 604800)//604800是7天的秒数,下面是删除超过7天的文件 80 { 81 remove(filename); 82 printf("remove file : %s \n" ,filename); 83 } 84 return 0; 85 } 86 87 } 88 89 //遍历子目录和目录中的文件 90 static int find_directory(const char *dirname) 91 { 92 DIR *dir; 93 char buffer[PATH_MAX + 2]; 94 char *p = buffer; 95 const char *src; 96 char *end = &buffer[PATH_MAX]; 97 int result; //返回结果 98 99 //copy目录名到buffer 100 src = dirname; 101 while (p < end && *src != '\0') { 102 *p++ = *src++; 103 } 104 *p = '\0'; 105 106 //打开目录 107 dir = opendir (dirname); 108 if (dir != NULL) { 109 struct dirent *ent; 110 111 while ((ent = readdir (dir)) != NULL) {//这里返回的是当前目录. 112 char *q = p; 113 char c; 114 115 //获得目录的最后一个字符 116 if (buffer < q) { 117 c = q[-1]; 118 } else { 119 c = ':'; 120 } 121 122 //在当前给出的目录下加上/ 123 if (c != ':' && c != '/' && c != '\\') { 124 *q++ = '/'; 125 } 126 127 //把文件名附加在后面 128 src = ent->d_name; //src 为根目录. 129 while (q < end && *src != '\0') { 130 *q++ = *src++; 131 } 132 *q = '\0'; 133 134 //根据是否是文件还是目录来选择操作 135 switch (ent->d_type) { 136 case DT_LNK: 137 case DT_REG: 138 //如果是文件 139 printf ("%s\n", buffer); 140 RemoveFile(buffer); 141 break; 142 143 case DT_DIR: 144 //如果是目录 145 if (strcmp (ent->d_name, ".") != 0 146 && strcmp (ent->d_name, "..") != 0) { 147 find_directory (buffer); 148 } 149 break; 150 151 default: 152 /* Ignore device entries */ 153 /*NOP*/; 154 } 155 156 } 157 158 closedir (dir); 159 result = 0; 160 161 } else { 162 //目录打不开 163 printf ("Cannot open directory %s\n", dirname); 164 result = -1; 165 } 166 167 return result; 168 }
dirent.h文件代码如下:
1 /* 2 * dirent.h - dirent API for Microsoft Visual Studio 3 * 4 * Copyright (C) 2006-2012 Toni Ronkko 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining 7 * a copy of this software and associated documentation files (the 8 * ``Software''), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sublicense, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included 15 * in all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 * IN NO EVENT SHALL TONI RONKKO BE LIABLE FOR ANY CLAIM, DAMAGES OR 21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 * OTHER DEALINGS IN THE SOFTWARE. 24 * 25 * $Id: dirent.h,v 1.20 2014/03/19 17:52:23 tronkko Exp $ 26 */ 27 #ifndef DIRENT_H 28 #define DIRENT_H 29 30 /* 31 * Define architecture flags so we don't need to include windows.h. 32 * Avoiding windows.h makes it simpler to use windows sockets in conjunction 33 * with dirent.h. 34 */ 35 #if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && defined(_M_IX86) 36 # define _X86_ 37 #endif 38 #if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && defined(_M_AMD64) 39 #define _AMD64_ 40 #endif 41 42 #include <stdio.h> 43 #include <stdarg.h> 44 #include <windef.h> 45 #include <winbase.h> 46 #include <wchar.h> 47 #include <string.h> 48 #include <stdlib.h> 49 #include <malloc.h> 50 #include <sys/types.h> 51 #include <sys/stat.h> 52 #include <errno.h> 53 54 /* Indicates that d_type field is available in dirent structure */ 55 #define _DIRENT_HAVE_D_TYPE 56 57 /* Indicates that d_namlen field is available in dirent structure */ 58 #define _DIRENT_HAVE_D_NAMLEN 59 60 /* Entries missing from MSVC 6.0 */ 61 #if !defined(FILE_ATTRIBUTE_DEVICE) 62 # define FILE_ATTRIBUTE_DEVICE 0x40 63 #endif 64 65 /* File type and permission flags for stat() */ 66 #if !defined(S_IFMT) 67 # define S_IFMT _S_IFMT /* File type mask */ 68 #endif 69 #if !defined(S_IFDIR) 70 # define S_IFDIR _S_IFDIR /* Directory */ 71 #endif 72 #if !defined(S_IFCHR) 73 # define S_IFCHR _S_IFCHR /* Character device */ 74 #endif 75 #if !defined(S_IFFIFO) 76 # define S_IFFIFO _S_IFFIFO /* Pipe */ 77 #endif 78 #if !defined(S_IFREG) 79 # define S_IFREG _S_IFREG /* Regular file */ 80 #endif 81 #if !defined(S_IREAD) 82 # define S_IREAD _S_IREAD /* Read permission */ 83 #endif 84 #if !defined(S_IWRITE) 85 # define S_IWRITE _S_IWRITE /* Write permission */ 86 #endif 87 #if !defined(S_IEXEC) 88 # define S_IEXEC _S_IEXEC /* Execute permission */ 89 #endif 90 #if !defined(S_IFIFO) 91 # define S_IFIFO _S_IFIFO /* Pipe */ 92 #endif 93 #if !defined(S_IFBLK) 94 # define S_IFBLK 0 /* Block device */ 95 #endif 96 #if !defined(S_IFLNK) 97 # define S_IFLNK 0 /* Link */ 98 #endif 99 #if !defined(S_IFSOCK) 100 # define S_IFSOCK 0 /* Socket */ 101 #endif 102 103 #if defined(_MSC_VER) 104 # define S_IRUSR S_IREAD /* Read user */ 105 # define S_IWUSR S_IWRITE /* Write user */ 106 # define S_IXUSR 0 /* Execute user */ 107 # define S_IRGRP 0 /* Read group */ 108 # define S_IWGRP 0 /* Write group */ 109 # define S_IXGRP 0 /* Execute group */ 110 # define S_IROTH 0 /* Read others */ 111 # define S_IWOTH 0 /* Write others */ 112 # define S_IXOTH 0 /* Execute others */ 113 #endif 114 115 /* Maximum length of file name */ 116 #if !defined(PATH_MAX) 117 # define PATH_MAX MAX_PATH 118 #endif 119 #if !defined(FILENAME_MAX) 120 # define FILENAME_MAX MAX_PATH 121 #endif 122 #if !defined(NAME_MAX) 123 # define NAME_MAX FILENAME_MAX 124 #endif 125 126 /* File type flags for d_type */ 127 #define DT_UNKNOWN 0 128 #define DT_REG S_IFREG 129 #define DT_DIR S_IFDIR 130 #define DT_FIFO S_IFIFO 131 #define DT_SOCK S_IFSOCK 132 #define DT_CHR S_IFCHR 133 #define DT_BLK S_IFBLK 134 #define DT_LNK S_IFLNK 135 136 /* Macros for converting between st_mode and d_type */ 137 #define IFTODT(mode) ((mode) & S_IFMT) 138 #define DTTOIF(type) (type) 139 140 /* 141 * File type macros. Note that block devices, sockets and links cannot be 142 * distinguished on Windows and the macros S_ISBLK, S_ISSOCK and S_ISLNK are 143 * only defined for compatibility. These macros should always return false 144 * on Windows. 145 */ 146 #define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO) 147 #define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) 148 #define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) 149 #define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK) 150 #define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK) 151 #define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR) 152 #define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK) 153 154 /* Return the exact length of d_namlen without zero terminator */ 155 #define _D_EXACT_NAMLEN(p) ((p)->d_namlen) 156 157 /* Return number of bytes needed to store d_namlen */ 158 #define _D_ALLOC_NAMLEN(p) (PATH_MAX) 159 160 161 #ifdef __cplusplus 162 extern "C" { 163 #endif 164 165 166 /* Wide-character version */ 167 struct _wdirent { 168 long d_ino; /* Always zero */ 169 unsigned short d_reclen; /* Structure size */ 170 size_t d_namlen; /* Length of name without \0 */ 171 int d_type; /* File type */ 172 wchar_t d_name[PATH_MAX]; /* File name */ 173 }; 174 typedef struct _wdirent _wdirent; 175 176 struct _WDIR { 177 struct _wdirent ent; /* Current directory entry */ 178 WIN32_FIND_DATAW data; /* Private file data */ 179 int cached; /* True if data is valid */ 180 HANDLE handle; /* Win32 search handle */ 181 wchar_t *patt; /* Initial directory name */ 182 }; 183 typedef struct _WDIR _WDIR; 184 185 static _WDIR *_wopendir (const wchar_t *dirname); 186 static struct _wdirent *_wreaddir (_WDIR *dirp); 187 static int _wclosedir (_WDIR *dirp); 188 static void _wrewinddir (_WDIR* dirp); 189 190 191 /* For compatibility with Symbian */ 192 #define wdirent _wdirent 193 #define WDIR _WDIR 194 #define wopendir _wopendir 195 #define wreaddir _wreaddir 196 #define wclosedir _wclosedir 197 #define wrewinddir _wrewinddir 198 199 200 /* Multi-byte character versions */ 201 struct dirent { 202 long d_ino; /* Always zero */ 203 unsigned short d_reclen; /* Structure size */ 204 size_t d_namlen; /* Length of name without \0 */ 205 int d_type; /* File type */ 206 char d_name[PATH_MAX]; /* File name */ 207 }; 208 typedef struct dirent dirent; 209 210 struct DIR { 211 struct dirent ent; 212 struct _WDIR *wdirp; 213 }; 214 typedef struct DIR DIR; 215 216 static DIR *opendir (const char *dirname); 217 static struct dirent *readdir (DIR *dirp); 218 static int closedir (DIR *dirp); 219 static void rewinddir (DIR* dirp); 220 221 222 /* Internal utility functions */ 223 static WIN32_FIND_DATAW *dirent_first (_WDIR *dirp); 224 static WIN32_FIND_DATAW *dirent_next (_WDIR *dirp); 225 226 static int dirent_mbstowcs_s( 227 size_t *pReturnValue, 228 wchar_t *wcstr, 229 size_t sizeInWords, 230 const char *mbstr, 231 size_t count); 232 233 static int dirent_wcstombs_s( 234 size_t *pReturnValue, 235 char *mbstr, 236 size_t sizeInBytes, 237 const wchar_t *wcstr, 238 size_t count); 239 240 static void dirent_set_errno (int error); 241 242 /* 243 * Open directory stream DIRNAME for read and return a pointer to the 244 * internal working area that is used to retrieve individual directory 245 * entries. 246 */ 247 static _WDIR* 248 _wopendir( 249 const wchar_t *dirname) 250 { 251 _WDIR *dirp = NULL; 252 int error; 253 254 /* Must have directory name */ 255 if (dirname == NULL || dirname[0] == '\0') { 256 dirent_set_errno (ENOENT); 257 return NULL; 258 } 259 260 /* Allocate new _WDIR structure */ 261 dirp = (_WDIR*) malloc (sizeof (struct _WDIR)); 262 if (dirp != NULL) { 263 DWORD n; 264 265 /* Reset _WDIR structure */ 266 dirp->handle = INVALID_HANDLE_VALUE; 267 dirp->patt = NULL; 268 dirp->cached = 0; 269 270 /* Compute the length of full path plus zero terminator */ 271 n = GetFullPathNameW (dirname, 0, NULL, NULL); 272 273 /* Allocate room for absolute directory name and search pattern */ 274 dirp->patt = (wchar_t*) malloc (sizeof (wchar_t) * n + 16); 275 if (dirp->patt) { 276 277 /* 278 * Convert relative directory name to an absolute one. This 279 * allows rewinddir() to function correctly even when current 280 * working directory is changed between opendir() and rewinddir(). 281 */ 282 n = GetFullPathNameW (dirname, n, dirp->patt, NULL); 283 if (n > 0) { 284 wchar_t *p; 285 286 /* Append search pattern \* to the directory name */ 287 p = dirp->patt + n; 288 if (dirp->patt < p) { 289 switch (p[-1]) { 290 case '\\': 291 case '/': 292 case ':': 293 /* Directory ends in path separator, e.g. c:\temp\ */ 294 /*NOP*/; 295 break; 296 297 default: 298 /* Directory name doesn't end in path separator */ 299 *p++ = '\\'; 300 } 301 } 302 *p++ = '*'; 303 *p = '\0'; 304 305 /* Open directory stream and retrieve the first entry */ 306 if (dirent_first (dirp)) { 307 /* Directory stream opened successfully */ 308 error = 0; 309 } else { 310 /* Cannot retrieve first entry */ 311 error = 1; 312 dirent_set_errno (ENOENT); 313 } 314 315 } else { 316 /* Cannot retrieve full path name */ 317 dirent_set_errno (ENOENT); 318 error = 1; 319 } 320 321 } else { 322 /* Cannot allocate memory for search pattern */ 323 error = 1; 324 } 325 326 } else { 327 /* Cannot allocate _WDIR structure */ 328 error = 1; 329 } 330 331 /* Clean up in case of error */ 332 if (error && dirp) { 333 _wclosedir (dirp); 334 dirp = NULL; 335 } 336 337 return dirp; 338 } 339 340 /* 341 * Read next directory entry. The directory entry is returned in dirent 342 * structure in the d_name field. Individual directory entries returned by 343 * this function include regular files, sub-directories, pseudo-directories 344 * "." and ".." as well as volume labels, hidden files and system files. 345 */ 346 static struct _wdirent* 347 _wreaddir( 348 _WDIR *dirp) 349 { 350 WIN32_FIND_DATAW *datap; 351 struct _wdirent *entp; 352 353 /* Read next directory entry */ 354 datap = dirent_next (dirp); 355 if (datap) { 356 size_t n; 357 DWORD attr; 358 359 /* Pointer to directory entry to return */ 360 entp = &dirp->ent; 361 362 /* 363 * Copy file name as wide-character string. If the file name is too 364 * long to fit in to the destination buffer, then truncate file name 365 * to PATH_MAX characters and zero-terminate the buffer. 366 */ 367 n = 0; 368 while (n + 1 < PATH_MAX && datap->cFileName[n] != 0) { 369 entp->d_name[n] = datap->cFileName[n]; 370 n++; 371 } 372 dirp->ent.d_name[n] = 0; 373 374 /* Length of file name excluding zero terminator */ 375 entp->d_namlen = n; 376 377 /* File type */ 378 attr = datap->dwFileAttributes; 379 if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) { 380 entp->d_type = DT_CHR; 381 } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) { 382 entp->d_type = DT_DIR; 383 } else { 384 entp->d_type = DT_REG; 385 } 386 387 /* Reset dummy fields */ 388 entp->d_ino = 0; 389 entp->d_reclen = sizeof (struct _wdirent); 390 391 } else { 392 393 /* Last directory entry read */ 394 entp = NULL; 395 396 } 397 398 return entp; 399 } 400 401 /* 402 * Close directory stream opened by opendir() function. This invalidates the 403 * DIR structure as well as any directory entry read previously by 404 * _wreaddir(). 405 */ 406 static int 407 _wclosedir( 408 _WDIR *dirp) 409 { 410 int ok; 411 if (dirp) { 412 413 /* Release search handle */ 414 if (dirp->handle != INVALID_HANDLE_VALUE) { 415 FindClose (dirp->handle); 416 dirp->handle = INVALID_HANDLE_VALUE; 417 } 418 419 /* Release search pattern */ 420 if (dirp->patt) { 421 free (dirp->patt); 422 dirp->patt = NULL; 423 } 424 425 /* Release directory structure */ 426 free (dirp); 427 ok = /*success*/0; 428 429 } else { 430 /* Invalid directory stream */ 431 dirent_set_errno (EBADF); 432 ok = /*failure*/-1; 433 } 434 return ok; 435 } 436 437 /* 438 * Rewind directory stream such that _wreaddir() returns the very first 439 * file name again. 440 */ 441 static void 442 _wrewinddir( 443 _WDIR* dirp) 444 { 445 if (dirp) { 446 /* Release existing search handle */ 447 if (dirp->handle != INVALID_HANDLE_VALUE) { 448 FindClose (dirp->handle); 449 } 450 451 /* Open new search handle */ 452 dirent_first (dirp); 453 } 454 } 455 456 /* Get first directory entry (internal) */ 457 static WIN32_FIND_DATAW* 458 dirent_first( 459 _WDIR *dirp) 460 { 461 WIN32_FIND_DATAW *datap; 462 463 /* Open directory and retrieve the first entry */ 464 dirp->handle = FindFirstFileW (dirp->patt, &dirp->data); 465 if (dirp->handle != INVALID_HANDLE_VALUE) { 466 467 /* a directory entry is now waiting in memory */ 468 datap = &dirp->data; 469 dirp->cached = 1; 470 471 } else { 472 473 /* Failed to re-open directory: no directory entry in memory */ 474 dirp->cached = 0; 475 datap = NULL; 476 477 } 478 return datap; 479 } 480 481 /* Get next directory entry (internal) */ 482 static WIN32_FIND_DATAW* 483 dirent_next( 484 _WDIR *dirp) 485 { 486 WIN32_FIND_DATAW *p; 487 488 /* Get next directory entry */ 489 if (dirp->cached != 0) { 490 491 /* A valid directory entry already in memory */ 492 p = &dirp->data; 493 dirp->cached = 0; 494 495 } else if (dirp->handle != INVALID_HANDLE_VALUE) { 496 497 /* Get the next directory entry from stream */ 498 if (FindNextFileW (dirp->handle, &dirp->data) != FALSE) { 499 /* Got a file */ 500 p = &dirp->data; 501 } else { 502 /* The very last entry has been processed or an error occured */ 503 FindClose (dirp->handle); 504 dirp->handle = INVALID_HANDLE_VALUE; 505 p = NULL; 506 } 507 508 } else { 509 510 /* End of directory stream reached */ 511 p = NULL; 512 513 } 514 515 return p; 516 } 517 518 /* 519 * Open directory stream using plain old C-string. 520 */ 521 static DIR* 522 opendir( 523 const char *dirname) 524 { 525 struct DIR *dirp; 526 int error; 527 528 /* Must have directory name */ 529 if (dirname == NULL || dirname[0] == '\0') { 530 dirent_set_errno (ENOENT); 531 return NULL; 532 } 533 534 /* Allocate memory for DIR structure */ 535 dirp = (DIR*) malloc (sizeof (struct DIR)); 536 if (dirp) { 537 wchar_t wname[PATH_MAX]; 538 size_t n; 539 540 /* Convert directory name to wide-character string */ 541 error = dirent_mbstowcs_s (&n, wname, PATH_MAX, dirname, PATH_MAX); 542 if (!error) { 543 544 /* Open directory stream using wide-character name */ 545 dirp->wdirp = _wopendir (wname); 546 if (dirp->wdirp) { 547 /* Directory stream opened */ 548 error = 0; 549 } else { 550 /* Failed to open directory stream */ 551 error = 1; 552 } 553 554 } else { 555 /* 556 * Cannot convert file name to wide-character string. This 557 * occurs if the string contains invalid multi-byte sequences or 558 * the output buffer is too small to contain the resulting 559 * string. 560 */ 561 error = 1; 562 } 563 564 } else { 565 /* Cannot allocate DIR structure */ 566 error = 1; 567 } 568 569 /* Clean up in case of error */ 570 if (error && dirp) { 571 free (dirp); 572 dirp = NULL; 573 } 574 575 return dirp; 576 } 577 578 /* 579 * Read next directory entry. 580 * 581 * When working with text consoles, please note that file names returned by 582 * readdir() are represented in the default ANSI code page while any output to 583 * console is typically formatted on another code page. Thus, non-ASCII 584 * characters in file names will not usually display correctly on console. The 585 * problem can be fixed in two ways: (1) change the character set of console 586 * to 1252 using chcp utility and use Lucida Console font, or (2) use 587 * _cprintf function when writing to console. The _cprinf() will re-encode 588 * ANSI strings to the console code page so many non-ASCII characters will 589 * display correcly. 590 */ 591 static struct dirent* 592 readdir( 593 DIR *dirp) 594 { 595 WIN32_FIND_DATAW *datap; 596 struct dirent *entp; 597 598 /* Read next directory entry */ 599 datap = dirent_next (dirp->wdirp); 600 if (datap) { 601 size_t n; 602 int error; 603 604 /* Attempt to convert file name to multi-byte string */ 605 error = dirent_wcstombs_s( 606 &n, dirp->ent.d_name, PATH_MAX, datap->cFileName, PATH_MAX); 607 608 /* 609 * If the file name cannot be represented by a multi-byte string, 610 * then attempt to use old 8+3 file name. This allows traditional 611 * Unix-code to access some file names despite of unicode 612 * characters, although file names may seem unfamiliar to the user. 613 * 614 * Be ware that the code below cannot come up with a short file 615 * name unless the file system provides one. At least 616 * VirtualBox shared folders fail to do this. 617 */ 618 if (error && datap->cAlternateFileName[0] != '\0') { 619 error = dirent_wcstombs_s( 620 &n, dirp->ent.d_name, PATH_MAX, 621 datap->cAlternateFileName, PATH_MAX); 622 } 623 624 if (!error) { 625 DWORD attr; 626 627 /* Initialize directory entry for return */ 628 entp = &dirp->ent; 629 630 /* Length of file name excluding zero terminator */ 631 entp->d_namlen = n - 1; 632 633 /* File attributes */ 634 attr = datap->dwFileAttributes; 635 if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) { 636 entp->d_type = DT_CHR; 637 } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) { 638 entp->d_type = DT_DIR; 639 } else { 640 entp->d_type = DT_REG; 641 } 642 643 /* Reset dummy fields */ 644 entp->d_ino = 0; 645 entp->d_reclen = sizeof (struct dirent); 646 647 } else { 648 /* 649 * Cannot convert file name to multi-byte string so construct 650 * an errornous directory entry and return that. Note that 651 * we cannot return NULL as that would stop the processing 652 * of directory entries completely. 653 */ 654 entp = &dirp->ent; 655 entp->d_name[0] = '?'; 656 entp->d_name[1] = '\0'; 657 entp->d_namlen = 1; 658 entp->d_type = DT_UNKNOWN; 659 entp->d_ino = 0; 660 entp->d_reclen = 0; 661 } 662 663 } else { 664 /* No more directory entries */ 665 entp = NULL; 666 } 667 668 return entp; 669 } 670 671 /* 672 * Close directory stream. 673 */ 674 static int 675 closedir( 676 DIR *dirp) 677 { 678 int ok; 679 if (dirp) { 680 681 /* Close wide-character directory stream */ 682 ok = _wclosedir (dirp->wdirp); 683 dirp->wdirp = NULL; 684 685 /* Release multi-byte character version */ 686 free (dirp); 687 688 } else { 689 690 /* Invalid directory stream */ 691 dirent_set_errno (EBADF); 692 ok = /*failure*/-1; 693 694 } 695 return ok; 696 } 697 698 /* 699 * Rewind directory stream to beginning. 700 */ 701 static void 702 rewinddir( 703 DIR* dirp) 704 { 705 /* Rewind wide-character string directory stream */ 706 _wrewinddir (dirp->wdirp); 707 } 708 709 /* Convert multi-byte string to wide character string */ 710 static int 711 dirent_mbstowcs_s( 712 size_t *pReturnValue, 713 wchar_t *wcstr, 714 size_t sizeInWords, 715 const char *mbstr, 716 size_t count) 717 { 718 int error; 719 720 #if defined(_MSC_VER) && _MSC_VER >= 1400 721 722 /* Microsoft Visual Studio 2005 or later */ 723 error = mbstowcs_s (pReturnValue, wcstr, sizeInWords, mbstr, count); 724 725 #else 726 727 /* Older Visual Studio or non-Microsoft compiler */ 728 size_t n; 729 730 /* Convert to wide-character string (or count characters) */ 731 n = mbstowcs (wcstr, mbstr, sizeInWords); 732 if (!wcstr || n < count) { 733 734 /* Zero-terminate output buffer */ 735 if (wcstr && sizeInWords) { 736 if (n >= sizeInWords) { 737 n = sizeInWords - 1; 738 } 739 wcstr[n] = 0; 740 } 741 742 /* Length of resuting multi-byte string WITH zero terminator */ 743 if (pReturnValue) { 744 *pReturnValue = n + 1; 745 } 746 747 /* Success */ 748 error = 0; 749 750 } else { 751 752 /* Could not convert string */ 753 error = 1; 754 755 } 756 757 #endif 758 759 return error; 760 } 761 762 /* Convert wide-character string to multi-byte string */ 763 static int 764 dirent_wcstombs_s( 765 size_t *pReturnValue, 766 char *mbstr, 767 size_t sizeInBytes, /* max size of mbstr */ 768 const wchar_t *wcstr, 769 size_t count) 770 { 771 int error; 772 773 #if defined(_MSC_VER) && _MSC_VER >= 1400 774 775 /* Microsoft Visual Studio 2005 or later */ 776 error = wcstombs_s (pReturnValue, mbstr, sizeInBytes, wcstr, count); 777 778 #else 779 780 /* Older Visual Studio or non-Microsoft compiler */ 781 size_t n; 782 783 /* Convert to multi-byte string (or count the number of bytes needed) */ 784 n = wcstombs (mbstr, wcstr, sizeInBytes); 785 if (!mbstr || n < count) { 786 787 /* Zero-terminate output buffer */ 788 if (mbstr && sizeInBytes) { 789 if (n >= sizeInBytes) { 790 n = sizeInBytes - 1; 791 } 792 mbstr[n] = '\0'; 793 } 794 795 /* Lenght of resulting multi-bytes string WITH zero-terminator */ 796 if (pReturnValue) { 797 *pReturnValue = n + 1; 798 } 799 800 /* Success */ 801 error = 0; 802 803 } else { 804 805 /* Cannot convert string */ 806 error = 1; 807 808 } 809 810 #endif 811 812 return error; 813 } 814 815 /* Set errno variable */ 816 static void 817 dirent_set_errno( 818 int error) 819 { 820 #if defined(_MSC_VER) && _MSC_VER >= 1400 821 822 /* Microsoft Visual Studio 2005 and later */ 823 _set_errno (error); 824 825 #else 826 827 /* Non-Microsoft compiler or older Microsoft compiler */ 828 errno = error; 829 830 #endif 831 } 832 833 834 #ifdef __cplusplus 835 } 836 #endif 837 #endif /*DIRENT_H*/
头文件请参考我的另外一篇博客:
http://www.cnblogs.com/matthew-2013/p/4676112.html