POSIX程序搜索整个文件系统中的文件

POSIX Program to search entire file system for a file

本文关键字:文件 文件系统 程序 搜索 POSIX      更新时间:2023-10-16

大家好。我需要编写一个POSIX程序,在整个文件系统中搜索从顶部目录开始的指定文件。我有一些代码根本没有完成,但是当我运行它,检查一个特定的文件是否是一个目录时,它说这个文件根本不是一个目录,它是一个目录,并试图移动到它,导致一个错误。我不确定如何才能告诉它这种类型的文件不是目录。

这是我的代码。我知道它不是完美的,我可能可以做一些不同的事情,以获取目录名并将它们传递给函数。不管怎样,我很确定我必须递归地做这个。

所讨论的文件是/dev/dry/card0,我正在从Debian虚拟机运行它。

#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <unistd.h>
#include <time.h>
#include <stdint.h>
#include <locale.h>
#include <langinfo.h>
#include <fcntl.h>
#include <iostream>
#include <stdio.h>
#include <string>
using namespace std; 
void SearchDirectory(string file_Name, string directory){
    string new_Directory = directory; 
    DIR *dirp; 
    dirp = opendir(directory.c_str()); 
    struct dirent *dptr; 
    struct stat statStruct; 
    while(dptr = readdir(dirp)){
        stat(dptr->d_name, &statStruct); 
        if( S_ISDIR(statStruct.st_mode) ){
            string check = dptr->d_name; 
            if ( check.compare(".") == 0 || check.compare("..") == 0 ){
                continue; 
            }
            else{
                cout << dptr->d_name << " is is a directory" << endl; 
                new_Directory.append("/");
                new_Directory.append(dptr->d_name);  
                SearchDirectory(file_Name, new_Directory); 
            }
        }
        else if( S_ISREG(statStruct.st_mode)){
            string check = dptr->d_name; 
            if( check.compare(file_Name) == 0){
                cout << "Found " << file_Name << " in " << directory << "/" << endl; 
            }
        }
    }
}
int main(int argc, char *argv[]){
    if(argc < 2 || argc > 2){
        cerr << "This program will find the specified file." << endl; 
        cerr << "Usage: mysearch <filename>" << endl; 
        return 1; 
    }
    string file_Name = argv[1]; 
    SearchDirectory(file_Name, "/"); 
    return 0; 
}

2需要一个有效的"find"命令

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char **argv)
{
    if (argc != 2) {
        fprintf(stderr, "Usage: %s <filename>", argv[0]);
    }
    execlp("find", "find", "/", "-name", argv[1], "-print", (char *)NULL);
    exit(EXIT_FAILURE);
}

->d_name只返回文件名,而不返回文件的路径。你需要启动(尚未构建)new_Directory而不是dptr->d_name

如果一个目录包含多个子目录,也会出现问题。对于第一个子目录之后的每个子目录,new_Directory的构造是不正确的。

您从未closedir您的目录句柄,所以您耗尽了资源。您还应该考虑在递归之前将整个目录加载到数组中,以避免句柄耗尽。

void SearchDirectory(string directory, string target_File_Name){
    DIR *dirp = opendir(directory.c_str());
    if (!dirp) {
        perror(("opendir " + directory).c_str());
        return;
    }
    struct dirent *dptr;
    while(dptr = readdir(dirp)){
        string file_Name = dptr->d_name;
        string file_Path = directory + "/" + file_Name;
        struct stat statStruct; 
        stat(file_Path.c_str(), &statStruct); 
        if( S_ISDIR(statStruct.st_mode) ){
            if ( file_Name.compare(".") == 0 || file_Name.compare("..") == 0 ){
                continue; 
            }
            SearchDirectory(file_Path, target_File_Name);
        }
        else if( S_ISREG(statStruct.st_mode)){
            if( file_Name.compare(target_File_Name) == 0){
                cout << file_Path << endl;
            }
        }
    }
    closedir(dirp);
}

更新:添加第二个问题。

更新:添加第三个问题。

更新:添加代码

不是为了OP的利益,他写道"关键是要想出一种自己做的方法",而是为了子孙后代的利益,这里有一种使用Boost的方法。文件系统:

#include <boost/filesystem.hpp>
namespace fs = boost::filesystem;
// sample usage: find_file("/home", ".profile");
void find_file( const fs::path& dirPath, const std::string& fileName) {
  fs::recursive_directory_iterator end;
  for(fs::recursive_directory_iterator it(dirPath); it != end; ++it) {
    if(it->leaf() == fileName)
      std::cout << it->path() << "n";
    if(fs::is_symlink(it->symlink_status()))
      it.no_push();
  }
}

使用fork, execv和Unix实现的/usr/bin/find进程并将其输出重定向到您的结果区域?

我不确定它是否是POSIX,但nftw库函数在UNIX (HP-UX, AIX, Linux)上广泛可用。

您的问题是"搜索匹配树"

BFS和DFS是典型的基本算法。给他们一个开始节点,然后开始。

如果你遵循符号链接,你会遇到麻烦;所以测试它们,不要遵循它们。

您应该能够将*FS算法中的每个点映射到目录操作。

既然c++是一个选项,为什么不使用Boost.Filesystem这样的东西呢?的提振。文件系统两分钟教程给出了如何使用目录迭代器实现搜索的示例。