场景
过程A 从Web服务收集文件,并将其复制到根文件夹。有时文件被复制到根目录的子文件夹中,例如:
c:\root\file1
c:\root\file2
c:\root\filea
c:\root\<unique random name>\fileA
我怀疑(但不确定)该Web服务在linux系统上运行,并且文件名区分大小写。因此,将文件复制到Windows文件系统上,并且在发生大写/小写冲突时,将文件复制到子文件夹中。子文件夹具有唯一的随机生成的名称。
过程B 扫描 root 和子文件夹中的文件以进行归档。正确归档的文件将被删除。 过程A 和过程B 不能同时运行。
现在是我的任务...我必须删除根目录的空子文件夹。
第一解决方案(最简单的解决方案)
过程B结束时,我可以扫描根目录的空子文件夹,结束然后删除它们。好吧...
DWORD DeleteEmptySubFolder(LPCSTR szRootFolder)
{
DWORD dwError = 0;
CString sFolder(szRootFolder);
sFolder += "*.*";
CFileFind find_folder;
BOOL bWorking = find_folder.FindFile(sFolder);
while (bWorking)
{
bWorking = find_folder.FindNextFile();
if(find_folder.IsDots())
continue;
if(find_folder.IsDirectory())
{
if(PathIsDirectoryEmpty(find_folder.GetFilePath()))
if(!RemoveDirectory(find_folder.GetFilePath()))
dwError = GetLastError();
}
}
return dwError;
}
现在是问题所在:过程B 我没有任何控制权,我不知道它何时结束。 步骤B 可以在归档每个文件后调用用户功能。
第二个解决方案(足够但不太有效)
我仍然可以调用上述函数
DWORD DeleteEmptySubFolder(LPCSTR szRootFolder)
这肯定不是很有效,它将扫描每个已归档文件的根目录的所有子文件夹,但只会删除空的子文件夹。
第三种解决方案(应该可以)
当过程B调用用户函数时,我知道根文件夹和已归档文件的完整路径。因此,我可以检查文件的文件夹是否为根目录的子文件夹:
#define EQUAL_FOLDER 0
#define A_SUBFOLDER_OF_B 1
#define B_SUBFOLDER_OF_A 2
#define UNRELATED_FOLDER 3
int CompareFolderHiearachy(LPCSTR szFolderA, LPCSTR szFolderB)
{
if(_stricmp(szFolderA, szFolderB))
{
// StrStrI - Windows function (from shlwapi.dll) which finds the first occurrence of a substring within a string (the comparison is not case-sensitive).
if(StrStrI(szFolderA, szFolderB) == szFolderA)
return A_SUBFOLDER_OF_B;
else if(StrStrI(szFolderB, szFolderA) == szFolderB)
return B_SUBFOLDER_OF_A;
else
return UNRELATED_FOLDER;
}
else
return EQUAL_FOLDER;
}
也许此解决方案在我的情况下可以正常工作,但它只能处理文件夹/文件名一致的情况。例如:
本地磁盘:
root: C:\folder\
filename: c:\folder\subfolder\fileA
映射的磁盘:
root: Z:\folder\
filename: Z:\folder\subfolder\fileA
UNC:
root: \\SERVER\folder\
filename: \\SERVER\folder\subfolder\fileA
现在是我的过于通用和抽象问题,在最坏的情况下,我可以检查两个文件夹的层次结构/分配吗?
\\server\folder1\folder2 (UNC)
z:\folder2 (network drive).
甚至更糟....
\\MYPC\folder1\folder2
c:\folder2
也许我在问一个有点不正当的问题……但这是非常具有挑战性和吸引力的,不是吗?
非常感谢您。
答案 0 :(得分:0)
我改进了第三种解决方案;它可以解决多种情况,但不幸的是它不能处理所有可能的情况。
#define ERROR_OCCURED -1
#define EQUAL_FOLDER 0
#define A_SUBFOLDER_OF_B 1
#define B_SUBFOLDER_OF_A 2
#define UNRELATED_FOLDER 3
int CompareFolderHiearachy(LPCSTR szFolderA, LPCSTR szFolderB)
{
char pBuffer[32767];
DWORD dwBufferLength = 32767;
UNIVERSAL_NAME_INFO * unameinfo = reinterpret_cast< UNIVERSAL_NAME_INFO *>(pBuffer);
DWORD dwRetVal = WNetGetUniversalName(szFolderA, UNIVERSAL_NAME_INFO_LEVEL, reinterpret_cast<LPVOID>(pBuffer), &dwBufferLength);
if(dwRetVal != NO_ERROR && dwRetVal != ERROR_NOT_CONNECTED && dwRetVal != ERROR_BAD_DEVICE)
return ERROR_OCCURED;
CString sFolderA(unameinfo->lpUniversalName ? unameinfo->lpUniversalName : szFolderA);
ZeroMemory(pBuffer, dwBufferLength);
dwRetVal = WNetGetUniversalName(szFolderB, UNIVERSAL_NAME_INFO_LEVEL, reinterpret_cast<LPVOID>(pBuffer), &dwBufferLength);
if(dwRetVal != NO_ERROR && dwRetVal != ERROR_NOT_CONNECTED && dwRetVal != ERROR_BAD_DEVICE)
return ERROR_OCCURED;
CString sFolderB(unameinfo->lpUniversalName ? unameinfo->lpUniversalName : szFolderB);
if(_stricmp(sFolderA, sFolderB))
{
// StrStrI - Windows function (from shlwapi.dll) which finds the first occurrence of a substring within a string (the comparison is not case-sensitive).
if(StrStrI(sFolderA, sFolderB) == static_cast<LPCSTR>(sFolderA))
return A_SUBFOLDER_OF_B;
else if(StrStrI(szFolderB, sFolderA) == static_cast<LPCSTR>(sFolderB))
return B_SUBFOLDER_OF_A;
else
return UNRELATED_FOLDER;
}
else
return EQUAL_FOLDER;
}
它不能解决以下问题:
folder A: \\MY_PC\shared_folder\folderA
folder B: C:\shared_folder
(\\MY_PC\shared_folder and C:\shared_folder are the sane folder)
和:
folder A: \\SERVER\shared_folderA\shared_folderB
folder B: \\SERVER\shared_folderB