简体   繁体   English

使用Cygwin的C ++递归文件/目录扫描

[英]C++ Recursive File/Directory scanning using Cygwin

I'm looking to write a portable filesystem scanner, capable of listing all files on a given directory path recursively. 我正在寻找一种便携式文件系统扫描程序,该程序能够递归列出给定目录路径上的所有文件。

To do this, I'm attempting to use cygwin for my compiler, making use of dirent.h and using the template: 为此,我尝试将cygwin用于我的编译器,使用dirent.h并使用模板:

#include <dirent.h> 
#include <stdio.h> 

int main(void)
{
  DIR           *d;
  struct dirent *dir;
  d = opendir(".");
  if (d)
  {
    while ((dir = readdir(d)) != NULL)
    {
      // Stuff
    }    
    closedir(d);
  }    
  return(0);
}

But need to add recursive directory searching as well. 但是还需要添加递归目录搜索。 To do this, my solution was to attempt to opendir() on the next file, and judge the error code to determine if it was successfully opened as a directory (which I would then recurse on) or if it was returned to be 'not a directory', which would then be listed as just a file. 为此,我的解决方案是尝试在下一个文件上打开opendir(),并判断错误代码以确定该文件是否已成功作为目录打开(然后将其递归至该目录)或是否返回为“ not”目录”,然后将其仅列为文件。

I admit it feels very klugey, but I have been unable to find a better method that can retain some portability (not win32), even after hours of searching. 我承认这感觉很笨拙,但是即使经过数小时的搜索,我仍然找不到更好的方法来保留某些可移植性(而不是win32)。

So my simplified solution (some psuedo for simplicity) is looking something like this: 因此,我的简化解决方案(为简单起见使用一些伪指令)看起来像这样:

int scan(string startdir)
{
  DIR           *d;
  struct dirent *dir;
  d = opendir(startdir.cstr());
  if (d)
  {
    while ((dir = readdir(d)) != NULL)
    {
      if( NOT '.' AND NOT '..')
      {
        if(temp = opendir(startdir + d) == NULL)
        {
           //FILE OR ERROR
        }else{
          //Opened successfully as a directory, so recurse
          scan(startdir + d->d_name + "\\");
        }
      }
    }
    closedir(d);
  }
  return(0);
}

This is just half rewritten psuedo code to keep it simple, but it seems to work (although I'm very open to suggestions on better ways to do this). 为了简化起见,这只是重写后的伪代码的一半,但它似乎可以工作(尽管我非常乐意接受有关执行此操作的更好方法的建议)。

The major issue I'm having, however, is a particular link file 'c:\\cygwin\\dev\\fd' which seems to be opening as a directory and recursively opening itself over and over infinitely. 但是,我遇到的主要问题是特定的链接文件'c:\\ cygwin \\ dev \\ fd',该文件似乎是作为目录打开的,并且递归地无限打开自己。

The 'fd' file is 4KB, 106 bytes with no extension and is a shortcut that does not point anywhere in Windows. “ fd”文件为4KB,106字节,无扩展名,是Windows中无法指向的快捷方式。

This error seems to indicate that either this kludgey method is bugged, or there's a problem in the cygwin implementation that I'm compiling in. 该错误似乎表明该kludgey方法已被错误修复,或者我正在编译的cygwin实现中存在问题。

As a short example: 作为一个简短的例子:

Error Reading: c:\cygwin\dev\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\0 No such file or directory

Excluding that directory, the search seems to work well. 排除该目录,搜索似乎运行良好。 But I'm not alright with hard coding an exclusion in to the scanner. 但是我很难对排除在扫描器中的代码进行硬编码。

If anyone has any ideas, suggestions, solutions, or alternative methods to this problem, your input would be appreciated. 如果有人对这个问题有任何想法,建议,解决方案或替代方法,您的意见将不胜感激。

Thanks. 谢谢。

If you can use boost, consider using boost::filesystem . 如果可以使用boost,请考虑使用boost :: filesystem The tutorials include a simple ls program that you can easily extend to work recursively. 这些教程包括一个简单的ls程序,您可以轻松地对其进行扩展以递归地工作。 The library also includes methods to query the types of files, which probably can solve your specific problem. 该库还包括查询文件类型的方法,这可能可以解决您的特定问题。

The culprit seems to be that the fd file links into /proc/ 罪魁祸首似乎是fd文件链接到/ proc /

I do not guarantee it to be true, but I am under the impression that this enables the scanner to recursively loop through its own directory structure. 我不保证它是真实的,但是我给人的印象是,这使扫描程序可以递归地遍历其自己的目录结构。

My efforts with readlink() to address this issue were promising at first, but I'm finding that with deeper levels of scanning, it becomes unreliable and the errors can still occur. 起初,我使用readlink()解决这个问题的努力很有希望,但是我发现随着扫描级别的提高,扫描变得不可靠,并且仍然可能发生错误。

I am now looking into other ways to achieve this functionality (ie boost::filesystem). 我现在正在研究实现此功能的其他方法(即boost :: filesystem)。

That is a virtual filesystem, maybe with symlinks. 那是一个虚拟文件系统,也许带有符号链接。 Cygwin supports symlinks, and you might have to factor that in. Cygwin支持符号链接,您可能必须考虑在内。

In your example you've tried to use opendir() again to determine whether something is a file or a directory. 在您的示例中,您尝试再次使用opendir()来确定某文件是文件还是目录。 You can do this more directly by using stat() from "sys/stat.h". 您可以通过使用“ sys / stat.h”中的stat()来更直接地执行此操作。 This should also be available in cygwin. cygwin中也应提供此功能。 You can use the macros S_ISREG() and S_ISDIR() to check for regular file or directory. 您可以使用宏S_ISREG()和S_ISDIR()来检查常规文件或目录。 Probably something like this: 大概是这样的:

    struct stat *buf = new struct stat;
    if(!stat(d->d_name, buf))
    {
        if(S_ISREG(buf->st_mode))
        {
            std::cout << "    File: " << entry->d_name << "\n";
        }
        if(S_ISDIR(buf->st_mode) &&  

Please have also a look at the answer I've provided to the other question . 也请看看我为其他问题提供的答案

You do realise that cygwin has all the UNIX tools. 您确实意识到cygwin具有所有UNIX工具。

Find is very usefull. 查找非常有用。

cygwin库同时具有ftw()和fts(),请使用其中之一。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM