C++ C++;如何使我的程序不会';是否删除正在使用的文件?
所以基本上,我列出了我临时目录中的所有文件,然后删除它们。显然,一些文件正在使用,而程序本身正在使用它正在删除的文件。我试图摆弄C++ C++;如何使我的程序不会';是否删除正在使用的文件?,c++,winapi,delete-file,C++,Winapi,Delete File,所以基本上,我列出了我临时目录中的所有文件,然后删除它们。显然,一些文件正在使用,而程序本身正在使用它正在删除的文件。我试图摆弄SHFileOperation,但没有成功。(tbh我不知道如何使用它)。在删除该文件之前,如何让它检查该文件是否正在被其他程序使用?谢谢 这给了我一个错误:fs::remove_all(entry.path()) 代码: #包括 #包括 #包括 #包括 #包括 #包括“cColor.h” 使用名称空间std; 名称空间fs=文件系统; 煤焦类型; int main()
SHFileOperation
,但没有成功。(tbh我不知道如何使用它)。在删除该文件之前,如何让它检查该文件是否正在被其他程序使用?谢谢
这给了我一个错误:fs::remove_all(entry.path())代码>
代码:
#包括
#包括
#包括
#包括
#包括
#包括“cColor.h”
使用名称空间std;
名称空间fs=文件系统;
煤焦类型;
int main()
{
SetConsoleTextAttribute(h,15);
while(true)
{
cout>类型;
如果(类型='n')
{
打破
出口(0);
}
else if(类型='y')
{
无法捕获异常只需忽略错误并继续。或者使用第二种形式并传递一个error\u code
参数。这样您就不会得到异常,您可以检查失败的原因
如果文件正在使用中,您会收到一个错误。因此您无法删除它。如果您没有权限,您也无法删除它
首先检查使用情况是一种竞争条件。检查后,文件可能会关闭,您可以安全地删除它。首先检查并删除它与删除它或尝试删除它失败没有区别。我想到了这一点。使用CreateFile
的递归删除函数。我的原始注释
也许您可以使用具有所需访问权限0的CreateFile并共享现有的打开模式。然后您必须检查失败原因。如果没有失败,请关闭并删除
不是100%正确。dwDesiredAccess应该是0
,dwShareMode应该是FILE\u SHARE\u DELETE
,dwCreationDisposition应该是OPEN\u EXISTING
,DWFlags和Attributes应该是FILE\u FLAG\u DELETE\u ON\u CLOSE
。如果收到有效句柄,则文件上最后一个CloseHandle
将导致d元素(见)
下面是一个例子:
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <tchar.h>
#include <iostream>
#include <filesystem>
#ifdef _UNICODE
auto& cout = std::wcout;
#else
using std::cout;
#endif // _UNICODE
using std::endl;
namespace fs=std::filesystem;
void deleteRecursive(const fs::path& path);
void tryDeleteFile(const fs::path& path);
int main(int argc, char* argv[])
{
TCHAR tempDir[255];
GetEnvironmentVariable(_T("TEMP"), tempDir, 255);
deleteRecursive(fs::path(tempDir));
return 0;
}
void deleteRecursive(const fs::path& path)
{
fs::directory_iterator dirs(path);
for (const auto& entry : dirs)
{
const auto& path = entry.path();
if (entry.is_directory())
{
deleteRecursive(path);
if (fs::is_empty(path))
{
if (!RemoveDirectory(path.c_str()))
{
cout << _T("Can't delete dir: ") << path << endl;
}
}
}
else
{
tryDeleteFile(path);
}
}
}
void tryDeleteFile(const fs::path& path)
{
const auto file = path.c_str();
HANDLE fileHandle = CreateFile(
file, // lpFileName,
0, // dwDesiredAccess,
FILE_SHARE_DELETE, // dwShareMode,
NULL, // lpSecurityAttributes,
OPEN_EXISTING, // dwCreationDisposition,
FILE_FLAG_DELETE_ON_CLOSE, // dwFlagsAndAttributes,
NULL // hTemplateFile
);
if (fileHandle == INVALID_HANDLE_VALUE)
{
DWORD lastErr = GetLastError();
if (lastErr != ERROR_FILE_NOT_FOUND) // gone in the mean time
{
cout << _T("Can't delete file: ") << file << endl;
}
}
else
{
CloseHandle(fileHandle);
}
}
#定义WIN32_LEAN_和_MEAN
#包括
#包括
#包括
#包括
#ifdef_UNICODE
auto&cout=std::wcout;
#否则
使用std::cout;
#endif/\u UNICODE
使用std::endl;
名称空间fs=std::filesystem;
void deleteRecursive(常量fs::path&path);
void tryDeleteFile(常量fs::path和path);
int main(int argc,char*argv[])
{
TCHAR tempDir[255];
GetEnvironmentVariable(_T(“TEMP”),tempDir,255);
deleteRecursive(fs::path(tempDir));
返回0;
}
void deleteRecursive(常量fs::path和path)
{
目录迭代器dirs(path);
用于(常数自动输入:dirs)
{
const auto&path=entry.path();
if(entry.is_directory())
{
删除递归(路径);
if(fs::is_empty(path))
{
如果(!RemoveDirectory(path.c_str()))
{
如果文件已经打开,则无法复制。通常无法删除它们。也许您可以使用所需的访问权限0
和共享模式open\u EXISTING
。然后您必须检查失败的原因。如果没有失败,请关闭并删除。但实际上,这只会引入另一场toctou竞赛。为什么不尝试删除它?系统已经执行了您试图复制的操作。@JonathanPotter您可以删除正在使用的文件(权限允许),在关闭所有打开的句柄之前,它实际上不会被删除。正在使用的文件并不意味着您不能对其调用DeleteFile
。如果文件的所有打开句柄都通过了file\u SHARE\u DELETE
SHARE模式,则尝试删除该文件不会导致ERROR\u SHARING\u违规
err或者。@I如果他们有,他们可能不在乎是否有人删除了它。@cal:我只是对声明的不准确发表了评论。
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <tchar.h>
#include <iostream>
#include <filesystem>
#ifdef _UNICODE
auto& cout = std::wcout;
#else
using std::cout;
#endif // _UNICODE
using std::endl;
namespace fs=std::filesystem;
void deleteRecursive(const fs::path& path);
void tryDeleteFile(const fs::path& path);
int main(int argc, char* argv[])
{
TCHAR tempDir[255];
GetEnvironmentVariable(_T("TEMP"), tempDir, 255);
deleteRecursive(fs::path(tempDir));
return 0;
}
void deleteRecursive(const fs::path& path)
{
fs::directory_iterator dirs(path);
for (const auto& entry : dirs)
{
const auto& path = entry.path();
if (entry.is_directory())
{
deleteRecursive(path);
if (fs::is_empty(path))
{
if (!RemoveDirectory(path.c_str()))
{
cout << _T("Can't delete dir: ") << path << endl;
}
}
}
else
{
tryDeleteFile(path);
}
}
}
void tryDeleteFile(const fs::path& path)
{
const auto file = path.c_str();
HANDLE fileHandle = CreateFile(
file, // lpFileName,
0, // dwDesiredAccess,
FILE_SHARE_DELETE, // dwShareMode,
NULL, // lpSecurityAttributes,
OPEN_EXISTING, // dwCreationDisposition,
FILE_FLAG_DELETE_ON_CLOSE, // dwFlagsAndAttributes,
NULL // hTemplateFile
);
if (fileHandle == INVALID_HANDLE_VALUE)
{
DWORD lastErr = GetLastError();
if (lastErr != ERROR_FILE_NOT_FOUND) // gone in the mean time
{
cout << _T("Can't delete file: ") << file << endl;
}
}
else
{
CloseHandle(fileHandle);
}
}