1. 程式人生 > >建立_中間/多級/巢狀_目錄/資料夾 (Visual C++ 原始碼)| Create intermediate directory (Visual C++ source code)

建立_中間/多級/巢狀_目錄/資料夾 (Visual C++ 原始碼)| Create intermediate directory (Visual C++ source code)

最近有個專案:用語音卡對呼叫中心中的話務錄音。
錄音檔案儲存在硬碟上,存放路徑的格式大致如下:

錄音檔案根目錄/接入號碼/日期/xxxxxxxxxxxxxx.wav

比如:

D:/Record/186025/20060427/1_13600001111.wav
D:/Record/186050/20060428/45_13600002222.wav


語音卡提供了開發包,在錄音時需要提供一個檔案的 Handle,該檔案也是通過開發包中
的 dx_fileopen 函式來 建立/開啟的,當目錄不存在時,dx_fileopen 函式並不自動
建立該目錄,所以需要由自己的程式來“關照”……

在試圖用 Win32 SDK 中的 CreateDirectory 函式建立資料夾時發現根本建立不了,
查閱 MSDN 得知 CreateDirectory 時必須確保上一級目錄必須存在,
否則建立會失敗,且 GetLastError() 返回 ERROR_PATH_NOT_FOUND 錯誤。

MSDN 當然也給出說明:可以用 SHCreateDirectoryEx 來建立多級目錄,
然而使用 SHxxx 函式需要額外連結 shell32.lib 庫,而且還得 #include <shlobj.h>,
這個我不大喜歡,於是乎自己寫了個函式,湊合著能用。



/*
描述:
	建立多級目錄
引數:
	strDirectory	要建立的目錄,比如 D:/Folder1/Folder2 或者 Folder1/Folder2/Folder3
返回值:
	true	建立成功 或 目錄已存在
	false	建立失敗
*/
bool CreateIntermediateDirectory (const char *strDirectory)
{
	if (strDirectory==NULL || strDirectory[0]==0)
	{
		return false;
	}

	bool bErrorOccur = false;
	CString csDirectory = strDirectory;
	CString csIntermediateDirectory;

	csDirectory.Replace ('/', '//');
	while (csDirectory.Replace ("////", "//") > 0);
	csDirectory.TrimRight ('//');

	int iLastIndex = 0;
	while (true)
	{
		iLastIndex = csDirectory.Find ('//', iLastIndex);

		if (iLastIndex == -1)
		{
			csIntermediateDirectory = csDirectory;
		}
		else
		{
			csIntermediateDirectory = csDirectory.Left (iLastIndex);
			iLastIndex ++;
		}

		// 如果該資料夾不存在,則建立之
		HANDLE hDirectory = 
		CreateFile (
			csIntermediateDirectory,
			GENERIC_READ,
			FILE_SHARE_READ,
			NULL,
			OPEN_EXISTING,
			FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS ,
			NULL
			);

		if (hDirectory == INVALID_HANDLE_VALUE)
		{
			BOOL bCreated = CreateDirectory (csIntermediateDirectory, NULL);
			if (!bCreated)
			{
				//logger.Log (LL_ERROR, "Create directory %s error! ErrorCode=%d",
				//	csIntermediateDirectory,
				//	GetLastError ()
				//	);
				bErrorOccur = true;
				break;
			}
		}
		else {
			CloseHandle (hDirectory);
		}

		if (iLastIndex == -1)
		{
			break;
		}
	}

	return !bErrorOccur;
}