我有任务使用win32 api(C ++)复制和删除一个巨大的文件夹,我使用Code Guru recurisive目录删除代码,这很好用,但是出现了一些问题。
百万感谢Lerooooy Jenkins指出它。
CodeGuru的递归删除链接无法正确处理 符号链接/交叉点。鉴于重新分析点可以指出 在任何地方(甚至是网络驱动器),删除时都需要小心 递归地只删除符号链接/结点而不是它 指向。处理这种情况的正确方法是检测 重新分析点(通过GetFileAttributes())并且不将其作为一个遍历 子目录。
所以我的问题是如何在删除或复制文件夹树时实际处理符号链接和连接。
对于摇摆问题,这里是CodeGuru目录删除的源代码
#include <string>
#include <iostream>
#include <windows.h>
#include <conio.h>
int DeleteDirectory(const std::string &refcstrRootDirectory,
bool bDeleteSubdirectories = true)
{
bool bSubdirectory = false; // Flag, indicating whether
// subdirectories have been found
HANDLE hFile; // Handle to directory
std::string strFilePath; // Filepath
std::string strPattern; // Pattern
WIN32_FIND_DATA FileInformation; // File information
strPattern = refcstrRootDirectory + "\\*.*";
hFile = ::FindFirstFile(strPattern.c_str(), &FileInformation);
if(hFile != INVALID_HANDLE_VALUE)
{
do
{
if(FileInformation.cFileName[0] != '.')
{
strFilePath.erase();
strFilePath = refcstrRootDirectory + "\\" + FileInformation.cFileName;
if(FileInformation.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
if(bDeleteSubdirectories)
{
// Delete subdirectory
int iRC = DeleteDirectory(strFilePath, bDeleteSubdirectories);
if(iRC)
return iRC;
}
else
bSubdirectory = true;
}
else
{
// Set file attributes
if(::SetFileAttributes(strFilePath.c_str(),
FILE_ATTRIBUTE_NORMAL) == FALSE)
return ::GetLastError();
// Delete file
if(::DeleteFile(strFilePath.c_str()) == FALSE)
return ::GetLastError();
}
}
} while(::FindNextFile(hFile, &FileInformation) == TRUE);
// Close handle
::FindClose(hFile);
DWORD dwError = ::GetLastError();
if(dwError != ERROR_NO_MORE_FILES)
return dwError;
else
{
if(!bSubdirectory)
{
// Set directory attributes
if(::SetFileAttributes(refcstrRootDirectory.c_str(),
FILE_ATTRIBUTE_NORMAL) == FALSE)
return ::GetLastError();
// Delete directory
if(::RemoveDirectory(refcstrRootDirectory.c_str()) == FALSE)
return ::GetLastError();
}
}
}
return 0;
}
int main()
{
int iRC = 0;
std::string strDirectoryToDelete = "c:\\mydir";
// Delete 'c:\mydir' without deleting the subdirectories
iRC = DeleteDirectory(strDirectoryToDelete, false);
if(iRC)
{
std::cout << "Error " << iRC << std::endl;
return -1;
}
// Delete 'c:\mydir' and its subdirectories
iRC = DeleteDirectory(strDirectoryToDelete);
if(iRC)
{
std::cout << "Error " << iRC << std::endl;
return -1;
}
// Wait for keystroke
_getch();
return 0;
}
答案 0 :(得分:3)
使用DeleteFile
删除文件符号链接。
使用RemoveDirectory
删除目录符号链接和联结。
换句话说,除了没有递归到具有FILE_ATTRIBUTE_REPARSE_POINT
属性的目录外,你就像对待任何其他文件或目录一样对待它们。
答案 1 :(得分:1)
实现目标的最简单方法和建议的方法是让系统完成工作。
SHFileOperation
并使用FO_DELETE
标记。IFileOperation
。这些API为您处理所有细节,并使用与shell相同的代码路径。如果需要,您甚至可以显示标准shell进度UI。