2013-03-09 33 views
3

在我的项目中,我需要用文本行显示用文件名过滤的用户驱动器上的所有文件。有没有API来做这种事情?Linux上的文件搜索API

在Windows上,我知道在WinAPI中有FindFirstFile和FindNextFile函数。

我使用C++/Qt。

+1

[查看](http://en.wikipedia.org/wiki/Find)? – tjameson 2013-03-09 11:06:51

+0

@tjameson这是命令行实用程序,我对C++函数感兴趣 – 2013-03-09 11:11:02

+0

我的意思是你可以掏空。你可以使用[Boost](http://www.boost.org/doc/libs/1_36_0/libs/filesystem/doc/index.htm)吗? – tjameson 2013-03-09 11:15:10

回答

3

Qt提供了QDirIterator类:

QDirIterator iter("/", QDirIterator::Subdirectories); 
while (iter.hasNext()) { 
    QString current = iter.next(); 
    // Do something with 'current'... 
} 
+0

它足够快吗?例如,使用模式'*'中问题中提到的WinAPI函数大约需要3秒才能找到约32000个文件。我不太确定Qt的工作如此之快。 – 2013-03-09 11:16:27

+1

@gxoptg这些函数与底层操作系统或文件系统一样快或慢。通过使用不同的函数来完成这一点,你几乎没有什么可以加速的。 – nos 2013-03-09 11:17:46

+0

检查它,运行速度比winapi版本o.O – 2013-03-09 11:29:06

4

ftw()和Linux有fts()

除了这些,你可以遍历目录,例如使用opendir8/readdir()

2

如果你正在寻找一个Unix命令,你可以这样做:

find source_dir -name 'regex'

如果你想这样做C++风格,我建议使用boost::filesystem。这是一个非常强大的跨平台库。
当然,你将不得不添加一个额外的库。

下面是一个例子:

std::vector<std::string> list_files(const std::string& root, const bool& recursive, const std::string& filter, const bool& regularFilesOnly) 
     { 
      namespace fs = boost::filesystem; 
      fs::path rootPath(root); 

      // Throw exception if path doesn't exist or isn't a directory. 
      if (!fs::exists(rootPath)) { 
       throw std::exception("rootPath does not exist"); 
      } 
      if (!fs::is_directory(rootPath)) { 
       throw std::exception("rootPath is not a directory."); 
      } 

      // List all the files in the directory 
      const std::regex regexFilter(filter); 
      auto fileList = std::vector<std::string>(); 

      fs::directory_iterator end_itr; 
      for(fs::directory_iterator it(rootPath); it != end_itr; ++it) { 

       std::string filepath(it->path().string()); 

       // For a directory 
       if (fs::is_directory(it->status())) { 

        if (recursive && it->path().string() != "..") { 
         // List the files in the directory 
         auto currentDirFiles = list_files(filepath, recursive, filter, regularFilesOnly); 
         // Add to the end of the current vector 
         fileList.insert(fileList.end(), currentDirFiles.begin(), currentDirFiles.end()); 
        } 

       } else if (fs::is_regular_file(it->status())) { // For a regular file 
        if (filter != "" && !regex_match(filepath, regexFilter)) { 
         continue; 
        } 

       } else { 
        // something else 
       } 

       if (regularFilesOnly && !fs::is_regular_file(it->status())) { 
        continue; 
       } 

       // Add the file or directory to the list 
       fileList.push_back(filepath); 
      } 

      return fileList; 
     } 
0

man findfind通过掩模(-name选项examole)