具有特定扩展名C / C ++的文件的高效搜索算法

时间:2011-09-29 15:04:11

标签: c++ c algorithm search filesystems

我想实现更快的目录搜索。 c / c ++中是否有可用的算法?

4 个答案:

答案 0 :(得分:4)

检查http://www.boost.org/doc/libs/1_47_0/libs/filesystem/v3/doc/index.htm上的boost :: filesystem库,你有一个recursive_directory_iterator类。

答案 1 :(得分:1)

本身没有C ++的东西,但是由于IO,目录搜索通常很慢,并且因为你必须统计每个文件(或任何操作系统等效的非unix系统)以找出除其名称之外的任何内容。提高速度的一种方法是继续编写一个服务器,将inode和文件名保存在内存中。当然,难点在于inode信息不是静态的。您需要监听文件系统更改以使缓存保持最新。这在Linux中肯定是可能的,但我在其他系统上没有经验。正如您所看到的,此问题的另一个主题是它非常系统且可能依赖于文件系统。也许像Boost :: Filesystem这样的系统独立库可以提供帮助,但我怀疑它实现了目录更新回调。

也许只需安装Google桌面?

答案 2 :(得分:0)

这是一个Windows解决方案(http://ideone.com/5dFVf)

class file_iterator : std::iterator<std::output_iterator_tag, const WIN32_FIND_DATA> {
    HANDLE handle;
    WIN32_FIND_DATA fdata;
public:
    file_iterator() :handle(NULL) { 
#ifdef _DEBUG
        memset(&fdata, 0, sizeof(fdata); 
#endif //_DEBUG
    }
    file_iterator(const std::wstring& path) :handle(FindFirstFile(path.c_str(), &fdata)) {}
    file_iterator(file_iterator&& b) :handle(b.handle) {b.handle = NULL;}
    file_iterator& operator=(file_iterator&& b) {close(); handle = b.handle; b.handle = NULL;}

    void close() {
        if (handle) 
            FindClose(handle); 
#ifdef _DEBUG
        memset(&fdata, 0, sizeof(fdata); 
#endif //_DEBUG
    }

    const WIN32_FIND_DATA& operator*() {return fdata;}
    file_iterator& operator++() {if (FindNextFile(handle , &fdata)==false) close(); return *this;}
    bool operator==(const file_iterator& b) {return handle == b.handle;}
    bool operator!=(const file_iterator& b) {return handle != b.handle;}
};

std::vector<std::wstring> 
    find_files_with_extension(
        const std::wstring& folder, 
        const std::wstring& extension, 
        std::vector<std::wstring>* result=NULL) 
{
    std::wstring filepath = folder + L"/*";
    std::vector<std::wstring> local_result;
    std::deque<std::wstring> todo;
    if (result == NULL) 
        result = &local_result;
    file_iterator iter(filepath);
    while(iter != file_iterator()) {
       std::wstring folder_file((*iter).cFileName);
       if ((*iter).dwFileAttributes | FILE_ATTRIBUTE_DIRECTORY)
           todo.push_back(folder_file);
       else if (folder_file.size() > extension.size() && folder_file.substr(folder_file.size()-extension.size())==extension)
           result->push_back(folder_file);
       ++iter;
    }
    for(int i=0; i<todo.size(); ++i)
        find_files_with_extension(todo[i], extension, result);
    return *result;
}

这使用广度优先搜索,它需要更多RAM并且稍微复杂一些,但由于缓存更快。

答案 3 :(得分:0)

目前,搜索是一项操作系统功能,那些试图实施第三方索引的人正在放弃。即使Google桌面也没有更新,大多数人认为它已经死了:

https://superuser.com/questions/194082/is-google-desktop-search-a-dead-project

如果你在某人的计算机上安装了一个搜索服务器并被抓住了磁盘和CPU - 并且你没有非常非常这样做的理由 - 你不仅会浪费一个很多时候编写代码和修补bug,但你也会疏远你的用户。

对于大多数跨平台应用,让用户在资源管理器/ Finder / Nautilus中查找文件然后让您的应用程序接受多文件拖放是一个更好的答案。此外,打开文件的大多数“常用对话框”现在都提供了内置的搜索功能。

如果您正在尝试为特定平台编写搜索加速工具,请加入该平台的API,甚至可以允许您补充其索引。这是Microsoft的Programmatic Search API:

http://msdn.microsoft.com/en-us/library/windows/desktop/bb266517(v=vs.85).aspx

OS / X有聚光灯API:

http://developer.apple.com/library/mac/#documentation/Carbon/Conceptual/SpotlightQuery/SpotlightQuery.html

我不太确定在Linux世界中是否有用于搜索的“正典”,但大多数相关版本的Ubuntu现在都附带跟踪器:

http://live.gnome.org/Tracker/Documentation