Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;如何使我的程序不会';是否删除正在使用的文件?_C++_Winapi_Delete File - Fatal编程技术网

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);
    }
}