您的位置:首页 > 运维架构 > Linux

linux下获取文件夹下子文件列表

2016-09-11 13:00 447 查看

linux下获取文件夹下子文件列表

预置条件:

1、只遍历当前目前,不遍历当前目录的子文件夹

2、根据用户提供的开始时间戳以及持续时间,返回在这个时间区间内被修改过的文件列表。

相关知识:

1、struct dirent结构体。存储目录中的文件信息(文件名、扩展名等等)。

include <dirent.h>
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) 文件名,最长255字符 */
}


2、struct stat 结构体。这个结构体是用来描述一个linux系统文件系统中的文件属性的结构。

struct stat
{
dev_t       st_dev;     /* ID of device containing file -文件所在设备的ID*/
ino_t       st_ino;     /* inode number -inode节点号*/
mode_t      st_mode;    /* protection -保护模式?*/
nlink_t     st_nlink;   /* number of hard links -链向此文件的连接数(硬连接)*/
uid_t       st_uid;     /* user ID of owner -user id*/
gid_t       st_gid;     /* group ID of owner - group id*/
dev_t       st_rdev;    /* device ID (if special file) -设备号,针对设备文件*/
off_t       st_size;    /* total size, in bytes -文件大小,字节为单位*/
blksize_t   st_blksize; /* blocksize for filesystem I/O -系统块的大小*/
blkcnt_t    st_blocks;  /* number of 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 - */
};


可以有两种方法来获取一个文件的属性:

1、通过路径:

int stat(const char *path, struct stat *struct_stat);

int lstat(const char *path,struct stat *struct_stat);

两个函数的第一个参数都是文件的路径,第二个参数是struct stat的指针。返回值为0,表示成功执行。

执行失败是,error被自动设置为下面的值:

EBADF: 文件描述词无效

EFAULT: 地址空间不可访问

ELOOP: 遍历路径时遇到太多的符号连接

ENAMETOOLONG:文件路径名太长

ENOENT:路径名的部分组件不存在,或路径名是空字串

ENOMEM:内存不足

ENOTDIR:路径名的部分组件不是目录

这两个方法区别在于stat没有处理字符链接(软链接)的能力,如果一个文件是符号链接,stat会直接返回它所指向的文件的属性;而lstat返回的就是这个符号链接的内容。这里需要说明一下的是软链接和硬链接的含义。我们知道目录在linux中也是一个文件,文件的内容就是这这个目录下面所有文件与inode的对应关系。那么所谓的硬链接就是在某一个目录下面将一个文件名与一个inode关联起来,其实就是添加一条记录!而软链接也叫符号链接更加简单了,这个文件的内容就是一个字符串,这个字符串就是它所链接的文件的绝对或者相对地址。

stat结构体中的st_mode 则定义了下列数种情况:

S_IFMT 0170000 文件类型的位遮罩

S_IFSOCK 0140000 scoket

S_IFLNK 0120000 符号连接

S_IFREG 0100000 一般文件

S_IFBLK 0060000 区块装置

S_IFDIR 0040000 目录

S_IFCHR 0020000 字符装置

S_IFIFO 0010000 先进先出

S_ISUID 04000     文件的(set user-id on execution)位
S_ISGID 02000     文件的(set group-id on execution)位
S_ISVTX 01000     文件的sticky位

S_IRUSR(S_IREAD) 00400     文件所有者具可读取权限
S_IWUSR(S_IWRITE)00200     文件所有者具可写入权限
S_IXUSR(S_IEXEC) 00100     文件所有者具可执行权限

S_IRGRP 00040             用户组具可读取权限
S_IWGRP 00020             用户组具可写入权限
S_IXGRP 00010             用户组具可执行权限

S_IROTH 00004             其他用户具可读取权限
S_IWOTH 00002             其他用户具可写入权限
S_IXOTH 00001             其他用户具可执行权限

上述的文件类型在POSIX中定义了检查这些类型的宏定义:
S_ISLNK (st_mode)    判断是否为符号连接
S_ISREG (st_mode)    是否为一般文件
S_ISDIR (st_mode)    是否为目录
S_ISCHR (st_mode)    是否为字符装置文件
S_ISBLK (s3e)        是否为先进先出
S_ISSOCK (st_mode)   是否为socket


3、vector容器。包括vector的排序。

sort 对给定区间所有元素进行排序

stable_sort 对给定区间所有元素进行稳定排序

partial_sort 对给定区间所有元素部分排序

partial_sort_copy 对给定区间复制并排序

nth_element 找出给定区间的某个位置对应的元素

is_sorted 判断一个区间是否已经排好序

partition 使得符合某个条件的元素放在前面

stable_partition 相对稳定的使得符合某个条件的元素放在前面

测试代码

//
//  testListDir.cpp
//
//
//  Created by jianjian Qi on 9/11/16.
//  Copyright © 2016 tgbtgb. All rights reserved.
//

#include <stdio.h>
#include <errno.h>
#include <dirent.h>
#include <sys/stat.h>
#include <time.h>
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>

using namespace std;

class FileInfo
b3ad
{
public:

char   fileName[128];   //文件名
time_t createTime;      //创建时间

};

/*
*函数功能    :比较两个文件信息的时间,实现升序
*
*fileLeft  :左文件信息
*fileRight :右文件信息
*
*返回值     :如果左文件小于右文件,返回true,否则返回false
*/
bool lessFunction(const FileInfo * fileLeft, const FileInfo * fileRight)
{
return (fileLeft->createTime < fileRight->createTime);
}

/*
*函数功能      :查找给定时间段内修改过的文件列表
*
*dirPath     :需要查找的文件夹
*beginTime   :文件开始时间
*duration    :查找时间区间大小
*vecFileinfo :查找到符合要求的文件,会把文件信息添加到vecFileinfo,用于返回给调用者使用
*
*返回值       : 0 代表成功,非0代表失败
*/
int getDirFileListByTimeRange(char * dirPath, time_t beginTime, time_t duration, vector<FileInfo *> &vecFileinfo)
{
DIR             *dataDir;
struct dirent   *ent;
struct stat         statbuf;
size_t                  fileNameLen;
time_t          endTime = beginTime + duration;

dataDir = opendir(dirPath);

if (dataDir == NULL)
{
printf("open [%s] error@%s\n", dirPath, strerror(errno));
return -1;
}

while ((ent = readdir(dataDir)) != NULL)
{
if ((ent->d_type & DT_REG) == 0)
{
continue;
}

lstat(ent->d_name,&statbuf);
fileNameLen = strlen(ent->d_name);

if (statbuf.st_ctime >= beginTime && statbuf.st_ctime <= endTime)
{
FileInfo * fileInfo = new FileInfo();
fileInfo->createTime = statbuf.st_ctime;
snprintf(fileInfo->fileName, 128, "%s", ent->d_name);
vecFileinfo.push_back(fileInfo);
}

}

return 0;
}

int main(int argc, char **argv)
{
if (argc != 4)
{
printf("input command param error\n");
return -1;
}

vector<FileInfo *> vecFileinfo;

if (getDirFileListByTimeRange(argv[1], atol(argv[2]), atol(argv[3]), vecFileinfo) != 0)
{
printf("get dir list error");
return -1;
}

if (vecFileinfo.size() > 0)
{
sort(vecFileinfo.begin(),vecFileinfo.end(),lessFunction);

struct tm *fileDate;
for (int i = 0 ; i < vecFileinfo.size(); i++)
{
FileInfo * fileInfo = (FileInfo *)vecFileinfo[i];
fileDate = localtime(&(fileInfo->createTime));
printf("%04d%02d%02d%02d%02d%02d %s\n",fileDate->tm_year+1900, fileDate->tm_mon+1, fileDate->tm_mday, fileDate->tm_hour, fileDate->tm_min, fileDate->tm_sec,fileInfo->fileName);
delete fileInfo;
fileInfo = NULL;
}
vecFileinfo.clear();
}
else
{
printf("empty\n");
return -1;
}

return 0;
}


编译

g++ testListDir.cpp

运行

#./a.out ~/Desktop/ 1473529951 600

20160911015231 2.ts

20160911015418 1.ts

20160911015605 3.ts
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  linux 遍历 目录