Windows下新建多级文件夹

http://blog.csdn.net/lgouc/article/details/8166522


 

Windows下新建多级文件夹

分类: Windows C/C++   713人阅读  评论(2)  收藏  举报
  1. 使用system函数调用系统命令"md"

注意:字符串变量的话赋值时要使用双斜杠"\\":

system("md C:\\newfolder\\");

如果需要动态新建目录的话:

char *path = "C:\\newfolder\\";

char swap[255];

sprintf(swap, "md %s", path);

system(swap);

不用判断返回值,系统会自动将错误信息打印到标准输出上.

 

  1. _mkdir()

#include <direct.h>

_mkdir("C:\\newfolder");//新建

_rmdir("C:\\newfolder");//删除

#include<io.h>

_access("C:\\newfolder");//判断文件夹是否存在

缺点是不能一下新建多层文件夹,可以裁剪字符串一级一级创建

如何新建多层目录:

//这里的const是对函数的使用者而言的,其实函数内部修改了该const字符串,但又还原了


[cpp]  view plain copy
  1. void initPath(const char *path)  
  2. {  
  3.     assert(path!= NULL);  
  4.   
  5.     // 一层层判断目录是否已存在,不存在就新建  
  6.     // 这里的字符串最后一个字符正常情况下是'\'  
  7.     // 所以最后可以不用再判断了  
  8.     // 之所以说上面一点是因为对_mkdir来说  
  9.     // "D:\document"和"D:\document\"没有区别  
  10.     char *tmp = (char *)path;  
  11.       
  12.     while (*tmp)  
  13.     {  
  14.         if (*tmp == '\\')  
  15.         {  
  16.             *tmp = '\0';  
  17.             if (_access(path, 0))// 头文件io.h  
  18.             {  
  19.                 if (_mkdir(path))  
  20.                 {  
  21.                     #ifdef _DEBUG  
  22.                     fprintf(stderr, "Failed to create directory %s:%s\n",   
  23.                         path, strerror(errno));  
  24.                     #endif  
  25.                 }  
  26.             }  
  27.             *tmp = '\\';  
  28.         }  
  29.         ++tmp;  
  30.     }  
  31. }  

  1. CreateDirectory()

API也不能新建多层文件夹,而且要打印该函数的出错信息也很复杂.Windows这一套真真的让人恶心.思路是一样的,先一层一层判断文件夹是否存在,如果不存在就新建.判断文件夹是否存在使用GetFileAttributes()函数,如果函数返回-1,说明文件/文件夹不存在;否则如果返回的属性有FILE_ATTRIBUTE_DIRECTORY,说明文件夹已存在.


[cpp]  view plain copy
  1. void createDirectory(const char *path)  
  2. {  
  3.     assert(path!= NULL);  
  4.     char *tmp = (char *)path;  
  5.     LPVOID lpMsgBuf;  
  6.   
  7.     while(*tmp)  
  8.     {  
  9.         if (*tmp == '\\')  
  10.         {  
  11.             *tmp = '\0';  
  12.             DWORD fileAttr = GetFileAttributes((LPCSTR) path);  
  13.             if (fileAttr == 0xFFFFFFFF || !(fileAttr & FILE_ATTRIBUTE_DIRECTORY))  
  14.             {  
  15.                 if (!CreateDirectory((LPCTSTR) path, NULL))  
  16.                 {  
  17.                     FormatMessage(  
  18.                         FORMAT_MESSAGE_ALLOCATE_BUFFER |   
  19.                         FORMAT_MESSAGE_FROM_SYSTEM |   
  20.                         FORMAT_MESSAGE_IGNORE_INSERTS,  
  21.                         NULL,  
  22.                         GetLastError(),  
  23.                         MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language  
  24.                         (LPTSTR) &lpMsgBuf,  
  25.                         0,  
  26.                         NULL   
  27.                         );  
  28.                     MessageBox(NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION);  
  29.                 }  
  30.             }  
  31.             *tmp = '\\';  
  32.         }  
  33.         ++tmp;  
  34.     }  
  35.     // Free the buffer.  
  36.     LocalFree(lpMsgBuf);  
  37. }  

关于FormatMessage函数,要多说一点关于Windows API错误(失败)信息的获取.看到网上说《Multitheading Applications inWin32(侯捷译)》书里讲述通过宏MTVERIFY就可以知道调用的Windows API函数错在什么地方:


[cpp]  view plain copy
  1. /* 
  2. * MtVerify.h 
  3. * 
  4. * Error handling for applications in 
  5. * "Multitheading Applications in Win32" 
  6. * 
  7. * The function PrintError() is marked as __inline so that it can be 
  8. * included from one or more C or C++ files without multiple definition 
  9. * errors. For the examples in this book, this works fine. 
  10. * To use the PrintError() in an application, it should be taken out, 
  11. * placed in its own source file, and the "__inline" declaration removed 
  12. * so the function will be globally available. 
  13. */  
  14.   
  15. #pragma comment(lib, "USER32")  
  16.   
  17. #include <crtdbg.h>  
  18. #define MTASSERT(a) _ASSERTE(a)  
  19.   
  20.   
  21. #define MTVERIFY(a) if (!(a)) PrintError(#a, __FILE__, __LINE__, GetLastError())  
  22.   
  23. __inline void PrintError(LPSTR linedesc, LPSTR filename, int lineno, DWORD errnum)   
  24. {  
  25.     LPSTR lpBuffer;  
  26.     char errbuf[256];  
  27.   
  28. #ifdef _WINDOWS  
  29.     char modulename[ MAX_PATH];  
  30. #else // _WINDOWS  
  31.     DWORD numread;  
  32. #endif // _WINDOWS  
  33.       
  34.     FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER  
  35.         | FORMAT_MESSAGE_FROM_SYSTEM,   
  36.         NULL,   
  37.         errnum,   
  38.         LANG_NEUTRAL,   
  39.         (LPTSTR) &lpBuffer,   
  40.         0,   
  41.         NULL);  
  42.       
  43.     wsprintf(errbuf, "\nThe following call failed at line %d in %s:\n\n"   
  44.         "%s\n\nReason: %s\n", lineno, filename, linedesc, lpBuffer);  
  45.   
  46. #ifdef _WINDOWS  
  47.     GetModuleFileName(NULL, modulename, MAX_PATH);  
  48.     MessageBox(NULL, errbuf, modulename, MB_ICONWARNING | MB_OK | MB_TASKMODAL | MB_SETFOREGROUND);  
  49. #else   
  50.     WriteFile(GetStdHandle(STD_ERROR_HANDLE), errbuf, strlen(errbuf), &numread, FALSE);  
  51.     Sleep(3000);  
  52. #endif  
  53.   
  54.     exit(EXIT_FAILURE);  
  55. }  

经过本人亲测,可用.那么上面的函数可以改为:


[cpp]  view plain copy
  1. #include "MtVerify.h"  
  2. void createDirectory(const char *path)  
  3. {  
  4.     assert(path != NULL);  
  5.     char *tmp = (char *)path;  
  6.   
  7.     while(*tmp)  
  8.     {  
  9.         if (*tmp == '\\')  
  10.         {  
  11.             *tmp = '\0';  
  12.             DWORD fileAttr = GetFileAttributes((LPCSTR) path);  
  13.             if (fileAttr == (DWORD) -1 || !(fileAttr & FILE_ATTRIBUTE_DIRECTORY))  
  14.             {  
  15.                 MTVERIFY(CreateDirectory((LPCTSTR) path, NULL));  
  16.             }  
  17.             *tmp = '\\';  
  18.         }  
  19.         ++tmp;  
  20.     }  
  21.   
  22. span style="white-space:pre">   </span>}  

  1. MakeSureDirectoryPathExists()

这绝对是一个暴力的函数,啥都不说了,直接用:

MTVERIFY(MakeSureDirectoryPathExists(path));

别忘了加上两句:

#include <ImageHlp.h>

#pragma comment(lib, "ImageHlp.lib")

加上一点:该函数强制要求参数字符串以反斜杠'\'结尾,如果不以'\'结尾,最后一层文件夹不会建立.

  1. 最后再说几个判断文件夹是否存在的方法
    1. PathFileExists() 可以判断文件或者文件夹是否存在:

if (PathFileExists(path)) {...}

  1. MFCCFileFind

使用CFileFind的成员函数FindFile(),FindNextFile()IsDirectory().


[cpp]  view plain copy
  1. void createDirectory(const char *path)  
  2. {  
  3.     assert(path != NULL);  
  4.     char *tmp = (char *)path;  
  5.     CFileFind ff;  
  6.       
  7.     // 不能搜索硬盘分区根目录,所以要略过  
  8.     // 如果严谨一些可以判断是否已到字符串结尾  
  9.     while (*tmp++ != '\\') {}  
  10.   
  11.     while (*tmp)  
  12.     {  
  13.         if (*tmp == '\\')  
  14.         {  
  15.             *tmp = '\0';  
  16.             if (ff.FindFile(path, 0))  
  17.             {  
  18.                 // 必须要调用一次FindNextFile()后才能判断  
  19.                 // IsDirectory(),不知道为什么  
  20.                 // 因为同一目录下的文件夹和文件也不能完全重名  
  21.                 // 所以不用担心会找到多个同名的文件/文件夹  
  22.                 ff.FindNextFile();  
  23.                 if (!ff.IsDirectory())  
  24.                 {  
  25.                     MTVERIFY(CreateDirectory((LPCTSTR) path, NULL));  
  26.                 }  
  27.             }  
  28.             else  
  29.             {  
  30.                 MTVERIFY(CreateDirectory((LPCTSTR) path, NULL));  
  31.             }  
  32.             *tmp = '\\';  
  33.         }  
  34.         ++tmp;  
  35.     }  
  36.   
  37. pan style="white-space:pre">        </span>}  

如果是非MFC应用程序,要加头文件afx.hWindows.h(VC6.0下顺序还不能反了,蛋疼),并设置工程为"Use MFC in a Shared DLL".编译通过.

 

  1. 和上面相似,使用Win32 API FindFirstFile()FindNextFile()


[cpp]  view plain copy
  1. void createDirectory(const char *path)  
  2. {  
  3.     assert(path != NULL);  
  4.     char *tmp = (char *)path;  
  5.       
  6.     // 不能搜索硬盘分区根目录,所以要略过  
  7.     // 如果严谨一些可以判断是否已到字符串结尾  
  8.     while (*tmp++ != '\\') {}  
  9.       
  10.     WIN32_FIND_DATA wfd;  
  11.   
  12.     while (*tmp)  
  13.     {  
  14.         if (*tmp == '\\')  
  15.         {  
  16.             *tmp = '\0';  
  17.             if (FindFirstFile(path, &wfd) == INVALID_HANDLE_VALUE ||   
  18.                 !(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))  
  19.             {  
  20.                 MTVERIFY(CreateDirectory((LPCTSTR) path, NULL));  
  21.             }  
  22.             *tmp = '\\';  
  23.         }  
  24.         ++tmp;  
  25.     }  
  26. }  

 上述处理的都是绝对路径(而且是以反斜杠结尾的绝对路径), 如果相对路径的话要稍作修改


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值