【问题标题】:Forcefully deleting a file using c++ in linux在linux中使用c ++强制删除文件
【发布时间】:2013-02-23 22:44:48
【问题描述】:

我有一个在 linux 服务器上运行的 c++ 代码。在代码中,我使用函数unlink(filename) 删除文件。由代码本身生成的临时文件已成功删除。但是我手动放置的文件,我的代码无法删除它们。可能是什么原因?

【问题讨论】:

  • my code is unable to delete them - 当您列出目录内容时,您还看到文件名吗?还是您只是观察到磁盘空间仍然被分配而不被回收?
  • 那个功能我不熟悉,应该是文件权限的问题。
  • @Andreas:是的。即使在执行代码之后,这些文件仍然存在。
  • unlink 确实“强制”删除 - 如果文件权限允许。仅当没有其他目录条目引用同一文件时才会回收空间 - 但应从目录中删除文件名。您真的应该按照@hyde 在答案中的建议检查返回码。
  • 关于 Unix 文件系统的重要一点是,unlink 只是删除了目录条目。即使这是指向文件的最后一个条目,如果文件在某个进程中打开,文件本身也不会被删除,直到其他进程实际关闭它(如果长期存在的守护进程继续打开,这可能会产生令人讨厌的磁盘使用泄漏但不关闭大文件)。

标签: c++ linux file


【解决方案1】:

试试这个:

#include <errno.h>
#include <string.h>

...

if (unlink(filename) == -1) {
    fprintf(stderr, "File '%s' unlink error (%d): %s\n", filename, errno, strerror(errno));
    // or just use perror("unlink") for less customizable error message
    // note: calling other functions before printing may change errno value
}

生成的错误消息应该能揭示问题所在。

这里是errno man pageunlink man page 会告诉它可以返回什么错误。


嗯,由于这实际上是一个 C++ 问题,您可以并且可能应该将 fprintf 替换为 std::cerr,但在这种情况下,可能需要先执行 int errtmp = errno 并使用那是为了避免 iostream 在检查之前弄乱它。

如果你想明确表示它是顶级命名空间中的一个符号,你也可以写::unlink(filename),至少有些人认为这是一种很好的做法,即使没有必要。

【讨论】:

  • 非常感谢@hyde 提供如此迅速而精彩的解决方案。我是一个白痴,只是传递文件名而不是完整路径,以防手动放置文件。错误信息解决了我的问题。再次感谢。 :)
  • @sajal 没问题。添加了一些关于 C++ 的细节,因为我的解决方案更像 C 代码。
  • 我没有使用 fprintf,而是将输出重定向到一个日志文件,所以我很安全 :)
【解决方案2】:

例如rm -f 的工作方式是,如果文件具有不允许删除的保护,它会尝试使用chmod()chown() 函数更改文件保护和所有权“使删除文件成为可能”。只有当用户是root 或文件实际上属于运行程序的用户时,这才真正保证工作。

请注意,这取决于系统,您不能编写代码以在 Windows 和类 Unix 操作系统上工作的方式更改文件权限等,如果您想在 Symbian OS 上执行此操作,它将是如何做到这一点的第三种变体,尽管在某些情况下可能有“Posix compatible”chmod()

【讨论】:

  • rm -f 不会尝试更改权限;它只是抑制了一些提示和错误报告。但是,C++17 提供了std::filesystem(基于 Boost,natch),让您可以根据需要操作权限。
猜你喜欢
  • 2019-02-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-11
  • 1970-01-01
相关资源
最近更新 更多