【问题标题】:Check whether file name already exists in a folder or not?检查文件夹中是否已经存在文件名?
【发布时间】:2014-07-22 15:21:59
【问题描述】:

在 C++ 中,我需要检查输入的文件名是否存在于该文件夹中。我正在使用 g++ 编译器为 Linux 编写代码。 请帮助大家:)

我在网上某处看到这段代码解决了我的问题,但我强烈认为它不能满足我的目的:

ofstream fout(filename);
if(fout)
{
cout<<"File name already exists";
return 1;
}

【问题讨论】:

  • ofstream改成ifstream会更好。
  • 你尝试了什么?在寻求帮助之前,您必须自己尝试

标签: c++ linux compiler-construction g++


【解决方案1】:

您可以通过使用ifstream 进行测试来做到这一点,但使用它和使用 C 级别的stat() 接口之间存在细微差别。

#include <cerrno>
#include <cstring>
#include <iostream>
#include <fstream>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

using namespace std;

int main (int argc, const char *argv[]) {
    if (argc < 2) {
        cerr << "Filepath required.\n";
        return 1;
    }

    ifstream fs(argv[1]);
    if (fs.is_open()) {
        fs.close();
        cout << "ifstream says file exists.\n";
    } else cout << "ifstream says file does not exist.\n";

    struct stat info;
    if ((stat(argv[1], &info)) == -1) {
        if (errno == ENOENT) cout << "stat() says file does not exist.\n";
        else cout << "stat() says " << strerror(errno) << endl;
    } else cout << "stat() says file exists.\n";

    return 0;
}
  • 如果您在存在的文件上运行此操作并且您对具有读取权限,则两种方式都会得到相同的答案。

  • 如果你在一个不存在的文件上运行这个,你会得到相同的结果。

  • 如果您对存在的文件运行此操作但您没有读取权限您会得到两个不同的答案fstream 会说该文件不存在,但stat() 会说它存在。请注意,如果您在同一目录中运行ls,它将显示该文件,即使您无法读取它;它确实存在。

因此,如果最后一种情况不重要——即,您无法读取的文件也可能不存在——然后使用ifstream 测试。但是,如果它很重要,请使用stat() 测试。请参阅man 2 stat2 很重要)了解更多信息,并记住,要使用它,您需要:

#include <cerrno>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h> 

如果stat() 失败,则需要cerrno 检查errno,这可能会发生。例如,如果路径中某个目录的读取权限被拒绝,则stat() 将失败,errno 将等于EACCES;如果你用上面的程序试试,你会得到stat() says Permission denied这并不表示文件存在。表示你无法检查它是否存在。

请注意,如果您以前没有使用过errno:您必须立即检查失败的呼叫,然后再进行其他可能设置不同的呼叫。但是,它是线程安全的。

【讨论】:

  • @didierc 您无法统计或打开您无法读取的目录中的文件,即使您知道它存在,您有确切的路径,并且该文件是世界可读的。在这种情况下,stat() 失败,而 errno 将 == EACCES。即,路径中不可读的目录是绝对的墙。
  • @didierc 确实。我在最后几段中添加了一些关于此的内容。
【解决方案2】:

如果你想成为跨平台和 C++'y,我推荐 Boost Filesystem library

出于您的目的,我认为类似于此 Boost 示例代码

#include <iostream>
#include <boost/filesystem.hpp>
using namespace boost::filesystem;

int main(int argc, char* argv[])
{
  path p (argv[1]);   // p reads clearer than argv[1] in the following code

  if (exists(p))    // does p actually exist?
  {
    if (is_regular_file(p))        // is p a regular file?   
      cout << p << " size is " << file_size(p) << '\n';

    else if (is_directory(p))      // is p a directory?
      cout << p << "is a directory\n";

    else
      cout << p << "exists, but is neither a regular file nor a directory\n";
  }
  else
    cout << p << "does not exist\n";

  return 0;
}

会做的。

【讨论】:

    【解决方案3】:

    也许你想要的是 fstat: http://codewiki.wikidot.com/c:system-calls:fstat

    【讨论】:

      猜你喜欢
      • 2022-08-19
      • 2021-11-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-27
      • 2013-10-28
      • 2012-02-05
      • 2015-03-26
      相关资源
      最近更新 更多