1. 程式人生 > >Windows下新建多級資料夾

Windows下新建多級資料夾

  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字串,但又還原了

	void initPath(const char *path)
	{
		assert(path!= NULL);
	
		// 一層層判斷目錄是否已存在,不存在就新建
		// 這裡的字串最後一個字元正常情況下是'\'
		// 所以最後可以不用再判斷了
		// 之所以說上面一點是因為對_mkdir來說
		// "D:\document"和"D:\document\"沒有區別
		char *tmp = (char *)path;
		
		while (*tmp)
		{
			if (*tmp == '\\')
			{
				*tmp = '\0';
				if (_access(path, 0))// 標頭檔案io.h
				{
					if (_mkdir(path))
					{
						#ifdef _DEBUG
						fprintf(stderr, "Failed to create directory %s:%s\n", 
							path, strerror(errno));
						#endif
					}
				}
				*tmp = '\\';
			}
			++tmp;
		}
	}

  1. CreateDirectory()

API也不能新建多層資料夾,而且要列印該函式的出錯資訊也很複雜.Windows這一套真真的讓人噁心.思路是一樣的,先一層一層判斷資料夾是否存在,如果不存在就新建.判斷資料夾是否存在使用GetFileAttributes()函式,如果函式返回-1,說明檔案/資料夾不存在;否則如果返回的屬性有FILE_ATTRIBUTE_DIRECTORY,說明資料夾已存在.

	void createDirectory(const char *path)
	{
		assert(path!= NULL);
		char *tmp = (char *)path;
		LPVOID lpMsgBuf;
	
		while(*tmp)
		{
			if (*tmp == '\\')
			{
				*tmp = '\0';
				DWORD fileAttr = GetFileAttributes((LPCSTR) path);
				if (fileAttr == 0xFFFFFFFF || !(fileAttr & FILE_ATTRIBUTE_DIRECTORY))
				{
					if (!CreateDirectory((LPCTSTR) path, NULL))
					{
						FormatMessage(
							FORMAT_MESSAGE_ALLOCATE_BUFFER | 
							FORMAT_MESSAGE_FROM_SYSTEM | 
							FORMAT_MESSAGE_IGNORE_INSERTS,
							NULL,
							GetLastError(),
							MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
							(LPTSTR) &lpMsgBuf,
							0,
							NULL 
							);
						MessageBox(NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION);
					}
				}
				*tmp = '\\';
			}
			++tmp;
		}
		// Free the buffer.
		LocalFree(lpMsgBuf);
	}

關於FormatMessage函式,要多說一點關於Windows API錯誤(失敗)資訊的獲取.看到網上說《Multitheading Applications inWin32(侯捷譯)》書裡講述通過巨集MTVERIFY就可以知道呼叫的Windows API函式錯在什麼地方:

	/*
	* MtVerify.h
	*
	* Error handling for applications in
	* "Multitheading Applications in Win32"
	*
	* The function PrintError() is marked as __inline so that it can be
	* included from one or more C or C++ files without multiple definition
	* errors. For the examples in this book, this works fine.
	* To use the PrintError() in an application, it should be taken out,
	* placed in its own source file, and the "__inline" declaration removed
	* so the function will be globally available.
	*/
	
	#pragma comment(lib, "USER32")
	
	#include <crtdbg.h>
	#define MTASSERT(a) _ASSERTE(a)
	
	
	#define MTVERIFY(a) if (!(a)) PrintError(#a, __FILE__, __LINE__, GetLastError())
	
	__inline void PrintError(LPSTR linedesc, LPSTR filename, int lineno, DWORD errnum) 
	{
	    LPSTR lpBuffer;
	    char errbuf[256];
	
	#ifdef _WINDOWS
	    char modulename[ MAX_PATH];
	#else // _WINDOWS
	    DWORD numread;
	#endif // _WINDOWS
	    
	    FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER
	        | FORMAT_MESSAGE_FROM_SYSTEM, 
	        NULL, 
	        errnum, 
	        LANG_NEUTRAL, 
	        (LPTSTR) &lpBuffer, 
	        0, 
	        NULL);
	    
	    wsprintf(errbuf, "\nThe following call failed at line %d in %s:\n\n" 
	        "%s\n\nReason: %s\n", lineno, filename, linedesc, lpBuffer);
	
	#ifdef _WINDOWS
	    GetModuleFileName(NULL, modulename, MAX_PATH);
	    MessageBox(NULL, errbuf, modulename, MB_ICONWARNING | MB_OK | MB_TASKMODAL | MB_SETFOREGROUND);
	#else 
	    WriteFile(GetStdHandle(STD_ERROR_HANDLE), errbuf, strlen(errbuf), &numread, FALSE);
	    Sleep(3000);
	#endif
	
	    exit(EXIT_FAILURE);
	}

經過本人親測,可用.那麼上面的函式可以改為:

	#include "MtVerify.h"
	void createDirectory(const char *path)
	{
		assert(path != NULL);
		char *tmp = (char *)path;
	
		while(*tmp)
		{
			if (*tmp == '\\')
			{
				*tmp = '\0';
				DWORD fileAttr = GetFileAttributes((LPCSTR) path);
				if (fileAttr == (DWORD) -1 || !(fileAttr & FILE_ATTRIBUTE_DIRECTORY))
				{
					MTVERIFY(CreateDirectory((LPCTSTR) path, NULL));
				}
				*tmp = '\\';
			}
			++tmp;
		}

}

  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().

		void createDirectory(const char *path)
		{
			assert(path != NULL);
			char *tmp = (char *)path;
			CFileFind ff;
			
			// 不能搜尋硬碟分割槽根目錄,所以要略過
			// 如果嚴謹一些可以判斷是否已到字串結尾
			while (*tmp++ != '\\') {}
		
			while (*tmp)
			{
				if (*tmp == '\\')
				{
					*tmp = '\0';
					if (ff.FindFile(path, 0))
					{
						// 必須要呼叫一次FindNextFile()後才能判斷
						// IsDirectory(),不知道為什麼
						// 因為同一目錄下的資料夾和檔案也不能完全重名
						// 所以不用擔心會找到多個同名的檔案/資料夾
						ff.FindNextFile();
						if (!ff.IsDirectory())
						{
							MTVERIFY(CreateDirectory((LPCTSTR) path, NULL));
						}
					}
					else
					{
						MTVERIFY(CreateDirectory((LPCTSTR) path, NULL));
					}
					*tmp = '\\';
				}
				++tmp;
			}

}

如果是非MFC應用程式,要加標頭檔案afx.hWindows.h(VC6.0下順序還不能反了,蛋疼),並設定工程為"Use MFC in a Shared DLL".編譯通過.

  1. 和上面相似,使用Win32 API FindFirstFile()FindNextFile()
		void createDirectory(const char *path)
		{
			assert(path != NULL);
			char *tmp = (char *)path;
			
			// 不能搜尋硬碟分割槽根目錄,所以要略過
			// 如果嚴謹一些可以判斷是否已到字串結尾
			while (*tmp++ != '\\') {}
			
			WIN32_FIND_DATA wfd;
		
			while (*tmp)
			{
				if (*tmp == '\\')
				{
					*tmp = '\0';
					if (FindFirstFile(path, &wfd) == INVALID_HANDLE_VALUE || 
						!(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
					{
						MTVERIFY(CreateDirectory((LPCTSTR) path, NULL));
					}
					*tmp = '\\';
				}
				++tmp;
			}
		}

 上述處理的都是絕對路徑(而且是以反斜槓結尾的絕對路徑), 如果相對路徑的話要稍作修改

相關推薦

Windows新建多級資料

使用system函式呼叫系統命令"md"注意:字串變數的話賦值時要使用雙斜槓"\\": system("md C:\\newfolder\\"); 如果需要動態新建目錄的話: char *path = "C:\\newfolder\\"; char swap[255]

Windows批量建立資料(批處理)

https://blog.csdn.net/qq_20881087/article/details/50969009 在Windows下批量建立資料夾 起因 新買了塊行動硬碟,準備建立個目錄結構方便後來的管理和使用。寫個批處理吧,也好久不用了。 使用方法 一共兩個檔案,md.bat和mkdir.ba

windows雙擊資料在新視窗開啟的情況修正

場景 莫名其妙的出現,在windows的資源管理器雙擊開啟檔案,卻在新的視窗顯示。無法通過修改資料夾選項修正。 解決方案 開啟登錄檔,在搜尋或者執行框中輸入regedit,開啟登錄檔。 在登錄檔搜尋框中輸入:HKEY_CLASSES_ROOT\Folder\sh

linux虛擬機器或伺服器在windows對映網路資料

 1:通過putty遠端虛擬機器 1:虛擬機器的網路設定改為橋接模式, 2:apt-get install ssh,reboot後,ifconfig檢視虛擬機器ip 3:在putty上登陸即可 2:對映網路資料夾 1、Samba的幾個套件:samba,samba-

WindowsVirtualBox 共享資料設定

原文地址:VirtualBox 共享檔案    原文作者:邊城浪子環境:主機(host):windowsXP虛擬機器:VirtualBox客戶機 (guest):slackware/ubuntu/...    看過我上一篇寫的為VirtualBox 安裝additions的朋

centos 掛載Windows的共享資料

按照位置開啟網路共享 選擇要共享資料夾: 右鍵點選屬性--> 點選共享 --》 選擇允許使用者(設定改使用者對此資料夾的許可權:安全--》編輯--》選擇使用者相關許可權允許下打鉤),點選高階--》選擇共享的檔名 centos 下: 1. 建立掛載到的位置:

Windows刪除.svn資料的最簡易方法

在使用svn時,有時不小心錯下載了檔案,或者檔案出現問題,需要刪除 .svn檔案,如果資料夾很多,一個一個手動刪除,非常麻煩,網上終於找到了一個簡單的方法,現分享(備註,有些人很不負責,貼了程式碼,也不測試,胡亂貼一通): SVN是我認為目前最方便的版本管理體系。我最早

Windows】Win10-更改c盤的使用者資料

轉載ooooohugh的文章,原文地址:https://blog.csdn.net/qq_33530388/article/details/71739845 當初 不小心用自己名字 作為計算機使用者名稱,後來 許多軟體因為 不支援 路徑中有中文,導致吃了不少的虧,心疼。。。。 下面說下怎

windows批量重新命名資料檔名稱

@echo off set a=00 setlocal EnableDelayedExpansion for %%n in (*.jpg) do ( set /A a+=1 ren "%%n" "Bus!a!.jpg" )1:在記事本中輸入以上程式碼;2:將記事本檔案另存為.

python3----專案-在windows系統對指定資料的檔案進行更改格式並隱藏檔案(或恢復正常)os、win32api、win32con、platform

python3—-專案-在windows系統下對指定資料夾內容的檔案進行更改格式並隱藏檔案(或恢復正常)os、win32api、win32con、platform 1、目標資料夾與檔案 C:\te

Linux和Windows系統C++讀取資料檔名

參考部落格     我的開發環境為Ubuntu+Qt,讀取資料夾下檔名時會找不到io.h,通過查詢資料瞭解到Windows和Linux下的標頭檔案是不一樣的,下面首先介紹Linux系統下檔名的獲取 一、Linux系統下檔名獲取 (1)C語言版本 //LINUX/UNIX

laravel框架上傳base64編碼圖片到多級資料

<?php public function uploadImg($params){ $params['uid'] = '123456'; $file = $params['file']; $uid = abs(intval($params['uid']));//123

Unity Assets目錄的特殊資料名稱

Assets目錄下,所有的Resources子資料夾,任何子目錄下都包括,比如./Assets/test/Resources  ,裡面的資源都會被打包。   轉自:https://www.douban.com/group/topic/59120314/?type=like

Android 5.1 建立多級資料失敗之奇怪的問題

問題: Android 5.1 建立多級資料夾失敗之奇怪的問題 原始碼: /** * 判斷資料夾是否建立 */ private static String foundFolder(String... str){ int length = str.length; String

windows清除訪問共享資料的登陸資訊

https://jingyan.baidu.com/article/c843ea0b70797e77931e4a96.html   當在命令提示視窗輸入net use命令時,會顯示本機快取的共享登入資訊,如果你想切換使用者,則可以刪除那條快取的記錄即可。   舉個例子,如上圖顯示,

在webcontent中新建資料中建立的JSP無法將資料傳給servlet

   相信很多寫程式的朋友都會建立很多資料夾來分類存放所寫的程式碼,本人也是如此,但是作為一個菜鳥,在做這件事的時候總會發生許多錯誤,我也一 一記錄下來,今次也不例外。    在寫一個關於登入頁面的簡單的JSP+Servlet時,新建立的資料夾,在裡面新寫

Linux遍歷資料

#include <dirent.h> #include <stdio.h> #include <stdlib.h> #include <string.h> char *dirname="/path/"; DIR *dirfile; dirfiles

Java刪除資料資料的子資料和子檔案

Java刪除資料夾及資料夾下的子資料夾和子檔案 public class Test { public static void main(String[] args){ File file = new File("D:\\a"); delAllFile(f

java tomcat有wtpwebapps資料 和 webapps資料區別

java tomcat下有wtpwebapps資料夾  和  webapps資料夾區別 (1)webapps : tomcat預設部署路徑 (2)wtpwebapps : eclipse預設部署路徑

純淨版linux (debian)掛載VirtualBox共享資料 virtual box虛擬機器在linux設定共享資料

使用的虛擬機器版本是:VirtualBox-5.2.8-121009 使用的linux版本是:Linux debian 4.9.0-7-amd64 tty 1. 開始配置 1.1:開啟虛擬機器設定,開啟你的VirtualBox軟體(主要先不要開啟linux系統)。選中你的虛擬機器後,