【问题标题】:Check if a file exists without opening it检查文件是否存在而不打开它
【发布时间】:2013-08-08 15:40:02
【问题描述】:

如何在继续我的程序之前检查文件是否存在于我的目录中?我已经阅读了尝试使用各种方法打开文件的答案,但我的问题是大多数时候,我正在检查的文件将损坏并且无法打开。这发生在我的程序的错误检查部分,只有在前面的代码中发生错误时才会触发。我想检查文件是否存在,如果是这样,请要求删除它,否则只需打印出一些消息。

我该怎么办?

(只是删除并接受错误会起作用,但我这样做是为了学习,所以我想正确地做......)

编辑:

我已经下载了 Boost 来使用文件系统库并编译它,看起来没有错误,但是当我尝试编译我的程序时,我得到了这个响应:

g++ program.cpp -I <path to>/boost_1_54_0 -o output

Undefined symbols for architecture x86_64:
"boost::filesystem::detail::status(boost::filesystem::path const&, boost::system::error_code*)", referenced from:
  boost::filesystem::exists(boost::filesystem::path const&)in cc1XX8rD.o
"boost::system::system_category()", referenced from:
  __static_initialization_and_destruction_0(int, int)in cc1XX8rD.o
"boost::system::generic_category()", referenced from:
  __static_initialization_and_destruction_0(int, int)in cc1XX8rD.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status

我在程序中使用 boost 的唯一地方是:

boost::filesystem::path my_file(s4);
if (boost::filesystem::exists(my_file)){ ...

【问题讨论】:

  • 你能不能简单地(尝试)删除文件并容忍删除尝试触发的任何错误,以防它不存在?

标签: c++ macos file error-handling delete-file


【解决方案1】:

使用stat()access()

#include <unistd.h>

int res = access(path, R_OK);
if (res < 0) {
    if (errno == ENOENT) {
         // file does not exist
    } else if (errno == EACCES) {
         // file exists but is not readable
    } else {
         // FAIL
    }
}

【讨论】:

【解决方案2】:

可以打开存在但包含损坏数据的文件而不会产生不良影响。只要您不尝试读取文件的内容即可。

但是,任何“检查它是否存在”都受TOCTUI 的约束,并且首先是完全没有必要的。只是尝试删除文件并接受删除可能并不总是有效是更好的方法。

【讨论】:

  • @Walter:想到了一些关于伟大思想的想法......;)
  • 如果伟大的思想是一样的,他们就不会那么伟大了,不是吗?
【解决方案3】:

如果你有机会在你的项目中使用 Boost,你可以选择Boost.Filesystem

#include <boost/filesystem.hpp>

boost::filesystem::path my_file("some/path/some_file");

if (boost::filesystem::exists(my_file))
{
    boost::filesystem::remove(my_file);
}
else
{
    std::cout << "File does not exist!" << std::endl;
}

此解决方案可跨多个系统移植Boost.Filesystem Implementation

【讨论】:

  • 看起来不错,但我不认为我想要所有的 Boost 文件。如果每次运行命令时终端都必须搜索所有这些文件以查看二进制文件是否存在,它会减慢我的速度吗?压缩文件超过 50MB,所以我假设里面有相当多的二进制文件。我可能完全错了,如果是这样,我会下载并安装它......
  • 我下载了 Boost 但我无法让它工作。我只编译了文件系统库,将 boost_1_54_0/stage/lib 目录添加到我的 PATH 中,使用 g++ 编译时包含带有 -I 标志的 boost_1_54_0 目录,在我的代码中包含 但我仍然不能让它工作。有关我遇到的错误,请参阅对我原始帖子的编辑。它不能与我的处理器一起使用还是我做错了什么?
  • g++ program.cpp -I /boost_1_54_0 -L/boost_1_54_0/lib -lboost_filesystem -lboost_system -o output
  • 编译得很好,但是当我运行它时,它给出了这个错误dyld: Library not loaded: libboost_filesystem.dylib Referenced from: &lt;path to compiled output&gt; Reason: image not found Trace/BPT trap: 5运行代码时我必须包含其他参数吗?
  • 您的程序似乎无法在任何系统路径中找到您的 boost 库。您可以使用以下方法解决此问题:export DYLD_LIBRARY_PATH=/path/to/boost/lib:$DYLD_LIBRARY_PATH
【解决方案4】:

您想在不尝试打开的情况下执行此操作。如果您改变主意并尝试打开文件:

bool file_exists(std::string filename){
   ifstream ifile(filename);
   return ifile;
}

有人说,这会自动关闭。我不知道。

而且,如果您不想打开文件,我认为有很多机会。我可以说出一个缓慢、老派和丑陋的解决方案,也许其他人会告诉你更好的解决方案。这里是:

system("dir > something.abc");

之后,您必须打开 something.abc 文件,并解析/解释这些行。您必须打开 something.abc 文件,但是,您不必打开您要分析的文件。

此解决方案将非常慢(0.5 秒,这对于 100 个文件来说并不好),您必须编写大量代码,而解析/解释“dir”命令的答案将非常复杂。

【讨论】:

  • 我包含了您提供的file_exists 函数,然后执行了if(file_exists(s4)==true){ //the file exists } else{ //it doesn't exist },但它似乎总是认为该文件不存在,即使它确实存在。我是不是做错了什么?
  • 这太糟糕了。请查看其他答案。
猜你喜欢
  • 1970-01-01
  • 2012-04-11
  • 2017-05-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多