【问题标题】:opening a file in random named folder using c/c++使用 c/c++ 打开随机命名文件夹中的文件
【发布时间】:2016-01-06 15:47:45
【问题描述】:

我正在尝试编写一个程序,它会自动打开并读取文件。但问题是文件存储在一个名称未知的文件夹中。我只知道文件夹的位置和文件名。如何在 char* 中获取该文件的路径?

编辑:例如:d:\files\<random folder>\data.txt

我不知道随机文件夹的名称,但我知道它存在于d:\files

【问题讨论】:

  • 你知道如何列出d:\files中的所有文件夹吗?
  • 两个目录有同一个文件会发生什么?
  • 目前没有 C++ 方法来迭代给定目录中的文件(当然,这是一种耻辱和可怕的遗留问题)。你必须使用像 boost 这样的第三方库。
  • 假设创建文件夹的人确保不同文件夹中没有同名文件。
  • 我强烈推荐使用/ 作为您的目录分隔符。 '\' 是转义字符,有些是控制字符,例如 \t\f\b(制表符、换页符和退格)。

标签: c++ windows file


【解决方案1】:

由于它被标记为windows,您不妨使用Windows API 函数:

枚举和遍历给定目录中的所有文件。

要检查目录,请查看WIN32_FIND_DATA 结构中包含的dwFileAttributes(由对Find...File() 的调用填充)。但请确保跳过 ... 目录。如果需要,这可以递归地完成。

您可以查看链接以获取一些示例,或查看Listing the Files in a Directory

如果您使用的是 MFC,则可以使用 CFileFind(它是 API 函数的包装器):

CFileFind finder;
BOOL bWorking = finder.FindFile(_T("*.*"));
while (bWorking)
{
   bWorking = finder.FindNextFile();
   TRACE(_T("%s\n"), (LPCTSTR)finder.GetFileName());
}

【讨论】:

    【解决方案2】:

    只是为了好玩,我使用 GCC 5 支持的新的、实验性的 <filesystem> FS Technical Specification 实现了这个。

    #include <iostream>
    #include <experimental/filesystem>
    
    // for readability
    namespace fs = std::experimental::filesystem;
    
    int main(int, char* argv[])
    {
        if(!argv[1])
        {
            std::cerr << "require 2 parameters, search directory and filename\n";
            return EXIT_FAILURE;
        }
    
        fs::path search_dir = argv[1];
    
        if(!fs::is_directory(search_dir))
        {
            std::cerr << "First parameter must be a directory: " << search_dir << '\n';
            return EXIT_FAILURE;
        }
    
        if(!argv[2])
        {
            std::cerr << "Expected filename to search for\n";
            return EXIT_FAILURE;
        }
    
        // file to search for
        fs::path file_name = argv[2];
    
        const fs::directory_iterator dir_end; // directory end sentinel
    
        // used to iterate through each subdirectory of search_dir
        fs::directory_iterator dir_iter(search_dir);
    
        for(; dir_iter != dir_end; ++dir_iter)
        {
            // skip non directories
            if(!fs::is_directory(dir_iter->path()))
                continue;
    
            // check directory for file
    
            // iterate through files in this subdirectory dir_iter->path()
            auto file_iter = fs::directory_iterator(dir_iter->path());
    
            for(; file_iter != dir_end; ++file_iter)
            {
                // ignore directories and wrong filenames
                if(fs::is_directory(file_iter->path())
                || file_iter->path().filename() != file_name)
                    continue;
    
                // Ok we found it (the first one)
                std::cout << "path: " << file_iter->path().string() << '\n';
                return EXIT_SUCCESS;
            }
        }
    
        // Not found
        std::cout << file_name << " was not found in " << search_dir.string() << '\n';
    
        return EXIT_FAILURE;
    }
    

    【讨论】:

      【解决方案3】:

      思路是:列出d:\files下的目录并尝试打开 每个目录下的文件。

      (还)没有标准的 C++ 方法来获取所有现有文件/目录。一个粗略但简单的方法是

      system("dir d:\\files /b /ad > tmpfile");
      

      这列出了所有目录 (/ad),重定向到一个临时文件。然后打开文件:

      std::ifstream list("tmpfile");
      

      然后阅读:

      std::string dirname;
      std::string filename;
      while (std::getline(list, dirname))
      {
          filename = "d:\\files\\" + dirname + "\\data.txt";
          if ( ... file exists ... )
              break;
      }
      

      我将此方法称为粗略,因为它存在难以/不可能解决的问题:

      • 它会覆盖一个可能有用的文件
      • 如果当前目录是只读的则不起作用
      • 它只适用于 Windows

      也许可以使用_popenfgets 而不是重定向到文件。

      【讨论】:

      • 我可以将文件存储在其他目录中吗?如果该文件夹是只读的
      • 是的。此外,如果您使用_popen,则不需要临时文件。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-03
      • 1970-01-01
      • 2018-12-31
      • 1970-01-01
      • 1970-01-01
      • 2016-01-29
      相关资源
      最近更新 更多