最近写代码有一个要遍历目录下的每一个文件并取得这个文件的绝对路径的需求,

我们知道linux c++中有system命令所以我在代码中 先生成了一个log,然后去读log文件的每一行文件名,然后给存储下来.

 void getFiles( vecotr<string> vecFileNames)
{ string path = "/home/yongchao/*.txt"; system("ls" + path + " > temp.log"); ifstream ifs("/home/yongchao/temp.log") //变量log里面每一个文件
if (ifs.fail())
{
return;
} string fileName;
while (getline(ifs, fileName))
{
vecFileNames.push_back("/home/yongchao/" + fileName);
} ifs.close();
ifs.clear();
return;
}

结果,可想而知,被项目经理狠狠的批评了一顿,说我太懒了,然后又被同事嘲笑的很是羞愧难当....首先是这个不能递归的把每一个子目录文件都保存;其次同事说,如果做临时测试你可以这些写,但是做项目不能这么干... 痛定思痛,乖乖的去网上搜索的linux c++的遍历目录文件名的解决方法.

 #include<sys/types.h>
#include<sys/stat.h>
#include<dirent.h> // /usr/include/dirent.h
#include<string>
#include<iostream>
using namespace std; int getAbsoluteFiles(string directory, vector<string>& filesAbsolutePath) //参数1[in]要变量的目录 参数2[out]存储文件名
{
DIR* dir = opendir(directory.c_str()); //打开目录 DIR-->类似目录句柄的东西
if ( dir == NULL )
{
cout<<directory<<" is not a directory or not exist!"<<endl;
return -;
} struct dirent* d_ent = NULL; //dirent-->会存储文件的各种属性
char fullpath[] = {};
char dot[] = "."; //linux每个下面都有一个 . 和 .. 要把这两个都去掉
char dotdot[] = ".."; while ( (d_ent = readdir(dir)) != NULL ) //一行一行的读目录下的东西,这个东西的属性放到dirent的变量中
{
if ( (strcmp(d_ent->d_name, dot) != )
&& (strcmp(d_ent->d_name, dotdot) != ) ) //忽略 . 和 ..
{
if ( d_ent->d_type == DT_DIR ) //d_type可以看到当前的东西的类型,DT_DIR代表当前都到的是目录,在usr/include/dirent.h中定义的
{ string newDirectory = directory + string("/") + string(d_ent->d_name); //d_name中存储了子目录的名字
if( directory[directory.length()-] == '/')
{
newDirectory = directory + string(d_ent->d_name);
} if ( - == getAbsolutFiles(newDirectory, filesAbsolutePath) ) //递归子目录
{
return -;
}
}
else //如果不是目录
{
string absolutePath = directory + string("/") + string(d_ent->d_name); //构建绝对路径
if( directory[directory.length()-] == '/') //如果传入的目录最后是/--> 例如a/b/ 那么后面直接链接文件名
{
absolutePath = directory + string(d_ent->d_name); // /a/b/1.txt
}
filesAbsolutePath.push_back(absolutePath);
}
}
} closedir(dir);
return ;
}

<<unix环境高级编程>>

http://blog.csdn.net/zhuyi2654715/article/details/7605051

 struct __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;

DIR结构体类似于FILE,是一个内部结构,有以下几个常用函数
DIR* opendir(const char* pathname); //
struct dirent* readdir(DIR* dp); //循环读取目录中的资讯
void rewinddir(DIR* dp); //重新读取目录资讯
int closedir(DIR* dp);
long telldir(DIR* dp);
void seekdir(DIR* dp, long loc);

目录文件(directory file): 这种文件包含了其他文件的名字以及指向与这些文件有关的信息的指针.
dirent 不仅仅指向目录,还指向目录中的具体文件
struct dirent
{
long d_info; //inode number 索引节点号
off_t d_off; //offset to this dirent 在目录文件中的偏移量
unsigned short d_reclen; //length of this d_name 文件长度,注意这里的长度不是文件大小,大小和长度是两回事,你可以用lseek将文件长度移的很长,但大小其实还是那么大
unsigned char d_type; //the type of d_name 文件类型
char d_name[NAME_MAX+]; //file name(null-terminated) 文件名,最初255
} 从上述定义看出,dirent结构体存储的关于文件的信息很少,所以dirent同样也是起着一个索引的作用,如果想获得类似 ls -l那种效果的文件信息, 必须要要下面的stat函数
int stat(const char* file_name, struct stat* buf); readdir函数会将读取到的文件名存储在结构体dirent的d_name成员中
而stat函数的作用就是获取d_name文件的详细信息,并将这些详细信息存储在下面的stat结构中
struct stat
{
mode_t st_mode; //文件访问权限
ino_t st_ino; //索引节点号
dev_t st_dev; //文件使用的设备号
dev_t st_rdev; //设备文件的设备号
nlink_t st_nlink; //设备的硬连接数
uid_t st_uid; //所有者用户识别号
gid_t st_gid; //组识别号
off_t st_size; //以字节为单位的文件容量
time_t st_atime; //最后一次访问该文件的时间
time_t st_mtime; //最后一次修改该文件的时间
time_t st_ctime; //最后一次改变该文件状态的时间
blksize_t st_blksize; //包含该文件的磁盘块的大小
blkcnt_t st_blocks; //该文件所占的磁盘块
}; 如果我们想获取a目录下b文件的详细信息的流程:
opendir函数打开目录a, 返回指向目录a的DIR结构体c
调用readdir(c)函数读取目录下所有文件(包括子目录), 返回指向目录a下所有文件的dirent结构体d
遍历d,调用stat(d->name, stat* e) 来获取每个文件的详细信息,存储在stat结构体e中

下面是一个打印目录下所有文件和目录的程序

再介绍一些其它的跟目录操作有关的函数

#include<unitstd.h>

//获得当前目录名称

char* getcwd(char* buf, size_t size); -->buf将会返回当前目录名称. 任何错误的发生,将会返回NULL.如果路径长度超过size, errno为ERANGE.getcwd返回的值永远没有symbol link的

char* getcwd(char* buf); --->getcwd是个危险的函数,一般都会强烈建议不要用,因为你无法确定最长的目录长度为多少.

//获得系统目录最大长度

long pathconf(char* path, int flag);

//改变目前所在目录

chdir/fchdir/chroot

int chdir(const char* pathname);--->根据pathname变更当前的所在目录,它只改变该程序的所在目录

int fchidr(int fd);--->根据已开启的fd(file descriptor)目录来变更

int chroot(const char* path);--->改变该程序的根目录所在.

//更改当前目录到上一级目录

if (chdir("..") == -)
{
perror("could not change current working directory\n");
return;
}

#include<sys/stat.h>

#include <sys/types.h>

int mkdir(const char* dirname, mode_t mode);  --->创建新目录出来,如果此目录或者档案已存在,则操作失败 例如 mkdir("/home/yongchao", 0755); //0755的0表示八进制

#incude<unistd.h>

int rmdir(char* pathname); --->删除pathname目录

linux c++ 遍历一个目录下的文件名 (包括子目录的文件名)的更多相关文章

  1. Java遍历一个目录下的所有文件

    Java遍历一个目录下的所有文件   Java工具中为我们提供了一个用于管理文件系统的类,这个类就是File类,File类与其他流类不同的是,流类关心的是文件的内容,而File类关心的是磁盘上文件的存 ...

  2. Python:遍历一个目录下所有的文件及文件夹,然后计算每个文件的字符和line的小程序

    编写了一个遍历一个目录下所有的文件及文件夹,然后计算每个文件的字符和line的小程序,先把程序贴出来. #coding=utf-8 ''' Created on 2014年7月14日 @author: ...

  3. Linux递归解压缩一个目录下的全部文件

    gunzip -r hongchangfirst/data 怎样递归删除那些剩余的非log结尾的文件? 先列出确认一下: find hongchangfirst/data -type f ! -nam ...

  4. Linux:删除一个目录下的所有文件,但保留一个指定文件

    面试题:删除一个目录下的所有文件,但保留一个指定文件 解答: 假设这个目录是/xx/,里面有file1,file2,file3..file10  十个文件 [root@oldboy xx]# touc ...

  5. md5目录下的文件包括子目录

    find ./ -type f -print0 | xargs -0 md5sum

  6. C#.NET中遍历指定目录下的文件(及所有子目录及子目录里更深层目录里的文件)

    //遍历一个目录下所有的文件列表,代码实例 DirectoryInfo dir = new DirectoryInfo(folderName);var list = GetAll(dir); /// ...

  7. linux-删除一个目录下的所有文件,但保留某个或者多个指定文件

    Linux:删除一个目录下的所有文件,但保留一个指定文件 面试题:删除一个目录下的所有文件,但保留一个指定文件 解答: 假设这个目录是/xx/,里面有file1,file2,file3..file10 ...

  8. python遍历一个目录,输出所有文件名

    python遍历一个目录,输出所有文件名 python os模块 os import os  def GetFileList(dir, fileList):  newDir = dir  if os. ...

  9. linux面试题:删除一个目录下的所有文件,但保留一个指定文件

    面试题:删除一个目录下的所有文件,但保留一个指定文件 解答: 假设这个目录是/xx/,里面有file1,file2,file3..file10 十个文件 [root@oldboy xx]# touch ...

随机推荐

  1. Python抓取淘宝IP地址数据

    def fetch(ip): url = 'http://ip.taobao.com/service/getIpInfo.php?ip=' + ip result = [] try: response ...

  2. ABAP ALV DEMO示例源码

    关于ALV表格颜色,感觉这种需求在项目中用到的时候不是很多,但是前一段时间面试的时候,面试官问了我关于ALV单元格颜色的问题. 以前了解过一点,回答的不是很好,后来百度了一下,大概了解了一些,今天工作 ...

  3. Servlet文件上传(ServletFIleUpload,DiskFileItemFactory,FileItem)

    1:我们学的是表单文件上传,就是在一个FORM中提交相应的信息,和之前我们的提交的注册信息之类的表单是不同的,所以要先改变一下FORM的属性,enctype="multipart/form- ...

  4. easyui常用控件样式收藏

    CSS类定义: div easyui-window                               window窗口样式 属性如下: 1)       modal:是否生成模态窗口.tru ...

  5. maven search

    开放的一些maven search 1:官方 http://search.maven.org/ 2:http://maven.ozacc.com/ 3:http://mvnrepository.com ...

  6. EasyUI-动态添加tab

    layout效果 代码: <%@ page language="java" contentType="text/html; charset=utf-8" ...

  7. linux 安装软件的地方

    用下边这个命令:mysqladmin -u root -p variables root是你的数据库帐号回车后会提示你输入密码,输入上边填写的帐号对应的密码 回车后出来一个大表,找到datadir这一 ...

  8. ubuntu中安装samba 分类: linux 学习笔记 ubuntu 2015-07-07 16:14 46人阅读 评论(0) 收藏

    为了方便的和Windows之间进行交互,samba必不可少. 当然,他的安装使用也很简单: 安装: sudo apt-get install samba sudo apt-get install sm ...

  9. git操作github

    转自http://www.cnblogs.com/fnng/archive/2012/01/07/2315685.html 怕找不到~ 本文在我之前的那篇<git/github学习笔记>的 ...

  10. 关于js中伪数组

    伪数组: 具有length属性: 按索引方式存储数据: 不具有数组的push().pop()等方法: 伪数组无法直接调用数组方法或期望length属性有什么特殊的行为,不具有数组的push().pop ...