C++ 为什么文件的std::remove总是返回-1?
我正在尝试删除一个文件(如果存在)。因此,首先我测试文件是否存在,如果存在,我使用std::remove将其删除。test.json包含一些与json相关的txt文件。我也包括在内C++ 为什么文件的std::remove总是返回-1?,c++,windows,C++,Windows,我正在尝试删除一个文件(如果存在)。因此,首先我测试文件是否存在,如果存在,我使用std::remove将其删除。test.json包含一些与json相关的txt文件。我也包括在内 std::string file_to_remove = "test.json"; std::ifstream f(file_to_remove.c_str()); if (f.good()) { int val = std::remove(file_to_remove.c_str());
std::string file_to_remove = "test.json";
std::ifstream f(file_to_remove.c_str());
if (f.good()) {
int val = std::remove(file_to_remove.c_str());
std::cout << "\nRemoving file : " << file_to_remove << " : ret val : " << val<< std::endl;
}
我本来希望返回值为0,但现在得到-1
我当前的输出是:
正在删除文件:test.json:ret val:-1
我还确保文件已关闭。您尝试删除打开的文件 在像Linux这样的Posix系统中,可以删除打开的文件。它将继续存在于磁盘上,并且只要打开它,您就可以继续使用它,但由于其目录项已被删除,其他人将看不到它。当你关闭文件时,它就会消失
在Windows中,无法删除打开的文件。使用perror或GetLastError检查错误代码。您试图删除打开的文件 在像Linux这样的Posix系统中,可以删除打开的文件。它将继续存在于磁盘上,并且只要打开它,您就可以继续使用它,但由于其目录项已被删除,其他人将看不到它。当你关闭文件时,它就会消失 在Windows中,无法删除打开的文件。使用perror或GetLastError检查错误代码。来自emphasis mine的文档: 如果该文件当前由该进程或另一进程打开,则该函数的行为是由实现定义的,尤其是POSIX系统取消与文件名的链接,尽管直到最后一个运行的进程关闭该文件时才回收文件系统空间;Windows不允许删除该文件 这意味着,如果文件处于打开状态,则在Windows上不会删除该文件。它将返回一个错误,例如-1 任何其他平台都可以是任何东西,因为它是实现定义的。我会研究一下您的平台/编译器,看看在打开的文件上调用std::remove的结果是什么 添加f后关闭;在std::remove ret val之前,现在为0 这很有意义,因为f.close关闭文件。文件现在已关闭,可以将其删除。从emphasis mine的文档中: 如果该文件当前由该进程或另一进程打开,则该函数的行为是由实现定义的,尤其是POSIX系统取消与文件名的链接,尽管直到最后一个运行的进程关闭该文件时才回收文件系统空间;Windows不允许删除该文件 这意味着,如果文件处于打开状态,则在Windows上不会删除该文件。它将返回一个错误,例如-1 任何其他平台都可以是任何东西,因为它是实现定义的。我会研究一下您的平台/编译器,看看在打开的文件上调用std::remove的结果是什么 添加f后关闭;在std::remove ret val之前,现在为0
这很有意义,因为f.close关闭文件。该文件现在已关闭,可以删除。您阅读过文档吗?如果打开该文件,则删除有点困难。您可能需要先关闭它。请使用例如检查该函数是否失败,返回-1时它会指示该函数是否失败。我还确保该文件已关闭@您应该研究如何在不打开文件的情况下确定文件是否存在。打开文件并检查正确返回值是不必要的,这是一种迂回的方法。您是否阅读了文档?如果您打开了文件,删除有点困难。您可能需要先关闭它。请使用例如检查函数是否失败,当返回-1时它会指示该函数是否失败。我还确保该文件已关闭@您应该研究如何在不打开文件的情况下确定文件是否存在。打开一个文件并检查正确的返回值是不必要的,这样做是一种迂回的方式。Windows可能允许您删除打开的文件,这取决于原始打开程序允许的内容。C++库甚至可能不尝试,具体实现可能。@ Anders CreateFile,FielySyryDelphi,我猜?我假设大多数实现只是尝试删除该文件,但由于在Windows中打开文件的过程必须特别允许其他人删除该文件,因此很少会成功:是的,就是这样。遗憾的是,Windows没有将其用于运行进程,因此您永远不能删除正在运行的.exe。@Anders,Windows在将可执行文件作为进程映像或共享库打开时使用了“删除共享”,这就是为什么允许我们重命名正在运行的可执行文件的原因。重命名文件需要使用DELETE访问打开它,因为它是一个原子取消链接的重新链接。但是,内存管理器不允许删除可执行映像,这就是为什么本例中的错误是错误访问被拒绝5,而不是错误共享违反32。此外,文件共享被正常删除与POSIX不同,因为Windows中的正常删除在关闭最后一个句柄之前不会解除文件与目录的链接。在那之前,任何处理都是必要的
删除权限可用于取消删除文件。Windows 10中的内核,特别是NTFS文件系统驱动程序,现在在重命名和删除文件时支持POSIX语义,例如FileDispositionInformationEx,当与删除共享结合时,它具有类似POSIX的行为。但是经典的Windows API函数(如DeleteFileW和MoveFileExW)不使用这些新操作。Windows可能允许您删除打开的文件,这取决于原始打开程序允许的内容。C++库甚至可能不尝试,具体实现可能。@ Anders CreateFile,FielySyryDelphi,我猜?我假设大多数实现只是尝试删除该文件,但由于在Windows中打开文件的过程必须特别允许其他人删除该文件,因此很少会成功:是的,就是这样。遗憾的是,Windows没有将其用于运行进程,因此您永远不能删除正在运行的.exe。@Anders,Windows在将可执行文件作为进程映像或共享库打开时使用了“删除共享”,这就是为什么允许我们重命名正在运行的可执行文件的原因。重命名文件需要使用DELETE访问打开它,因为它是一个原子取消链接的重新链接。但是,内存管理器不允许删除可执行映像,这就是为什么本例中的错误是错误访问被拒绝5,而不是错误共享违反32。此外,文件共享被正常删除与POSIX不同,因为Windows中的正常删除在关闭最后一个句柄之前不会解除文件与目录的链接。在此之前,任何具有DELETE访问权限的句柄都可以用于取消删除文件。Windows 10中的内核,特别是NTFS文件系统驱动程序,现在在重命名和删除文件时支持POSIX语义,例如FileDispositionInformationEx,当与删除共享结合时,它具有类似POSIX的行为。但这些新操作并没有被经典的Windows API函数(如DeleteFileW和MoveFileExW)使用。