[C++]linux下实现ls()函数遍历目录

转载请注明原创:http://www.cnblogs.com/StartoverX/p/4600794.html 

需求:在linux下遍历目录,输出目录中各文件名。

  在linux下遍历目录的相关函数有:

  #include <dirent.h>

  DIR* opendir(const char* dir_path);

  struct dirent* readdir(DIR* dirp);

  int closedir(DIR* dirp);

  int lstat(const chat* filename,struct stat* st);

在这里涉及到几个结构体:DIR,struct dirent,struct stat:

  DIR结构体是一个内部结构,类似与FILE,用来保存当前被读取的目录的信息:

truct __dirstream 
{ 
    void     *__fd; 
    char     *__data; 
    int        __entry_data; 
    char     *__ptr; 
    int       __entry_ptr; 
    size_t  __allocation; 
    size_t  __size; 
    __libc_lock_define (, __lock) 
}; 
      
typedef struct __dirstream DIR;

  struct dirent,指向文件夹下的目录内容:

struct dirent
{
long d_ino; /* inode number 索引节点号 */
off_t d_off; /* offset to this dirent 在目录文件中的偏移 */
unsigned short d_reclen; /* length of this d_name 文件名长 */
unsigned char d_type; /* the type of d_name 文件类型 */
char d_name [NAME_MAX+1]; /* file name (null-terminated) 文件名,最长256字符 */
}

  struct stat结构体保存文件信息,通过stat(),fstat(),lstat()函数返回,这三个函数的区别是:stat()传入文件路径得到stat,lstat()当传入的是符号链文件时,得到的是符号链文件的信息而不是符号链指向的文件,fstat()传入的是文件描述符而不是文件路径。

struct stat {
    dev_t     st_dev;     /* ID of device containing file */
    ino_t     st_ino;     /* inode number */
    mode_t    st_mode;    /* protection */
    nlink_t   st_nlink;   /* number of hard links */
    uid_t     st_uid;     /* user ID of owner */
    gid_t     st_gid;     /* group ID of owner */
    dev_t     st_rdev;    /* device ID (if special file) */
    off_t     st_size;    /* total size, in bytes */
    blksize_t st_blksize; /* blocksize for file system I/O */
    blkcnt_t  st_blocks;  /* number of 512B blocks allocated */
    time_t    st_atime;   /* time of last access */
    time_t    st_mtime;   /* time of last modification */
    time_t    st_ctime;   /* time of last status change */
};

  以下是ls()函数的全部实现,通过opendir()得到DIR*指针,readdir()函数获得指向struct dirent结构的指针,再通过struct stat得到每一个文件的信息。按字母顺序先输出目录文件名,再输出普通文件。

int ls(std::string path,std::string& ret)
{
    DIR* dirp = opendir(path.c_str());
    if(!dirp)
    {
        return -1;        
    }
    struct stat st;
    struct dirent *dir;
    std::vector<std::string> file_name;
    std::vector<std::string> dir_name;
    while((dir = readdir(dirp)) != NULL)
    {
        if(strcmp(dir->d_name,".") == 0 ||
                   strcmp(dir->d_name,"..") == 0)    
        {
            continue;
        }
        std::string full_path = path + dir->d_name;
        if(lstat(full_path.c_str(),&st) == -1)
        {
            continue;
        }
        std::string name = dir->d_name;

        //replace the blank char in name with "%$".
        while(name.find(" ") != std::string::npos)
        {
            name.replace(name.find(" "),1,"$%");    
        }

        if(S_ISDIR(st.st_mode))   //S_ISDIR()宏判断是否是目录文件
        {
            name += "[d]";
            dir_name.push_back(name);
        }
        else
        {
            file_name.push_back(name);
        }
    }

    closedir(dirp);

    sort(file_name.begin(),file_name.end());
    sort(dir_name.begin(),dir_name.end());
    
    std::stringstream ss_ret;
    int count = 0;

    for(auto i=dir_name.begin();i!=dir_name.end();i++)
    {
        ss_ret<<*i;    
        count++;
        if(count%5 == 0)
        {
            ss_ret<<std::endl;
        }
        else
        {
            ss_ret<<"  ";
        }
    }
    
    for(auto i=file_name.begin();i!=file_name.end();i++)
    {
        ss_ret<<*i;
        count++;
        if(count%5 == 0) //每五个名字回车。
        {
            ss_ret<<std::endl;
        }
        else
        {
            ss_ret<<"  ";
        }
    }

    ret = ss_ret.str();
    
    return 0;
}

 

  

转载于:https://www.cnblogs.com/StartoverX/p/4600794.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值