项目总结 之 C++获取文件夹下所有文件

在最近做的一个项目中,需要一个获取一个文件夹下文件的功能,之前一直对文件的操作一直停留在对文件的读写,还从来没有接触过文件夹相关的操作。因此,这次有幸使用了,还是记录下来吧,以后肯定也会有很多使用的机会。

参考博客
C++ 文件/文件夹操作

1 本人项目中使用的方法(算比较蠢的吧,还是代码写的太少了。。)

需要使用dirent.h这个头文件,然后使用的基本流程是opendir ->readdir->closedir
和FILE类型不同,这里opendir返回的是DIR类型的指针。readdir返回的是struct dirent结构体类型。

结构体的详细内容如下:

struct dirent
  {
#ifndef __USE_FILE_OFFSET64
    __ino_t d_ino;
    __off_t d_off;
#else
    __ino64_t d_ino;
    __off64_t d_off;
#endif
    unsigned short int d_reclen;
    unsigned char d_type;
    char d_name[256];       /* We must not include limits.h! */
  }; 
//查找path路径下的所有文件
vector<string> findFileNames(const char* path){
	//用于保存文件名
    vector<string> fileNames;
    //dirent指针是一个结构体指针
    struct dirent *ptr;
    DIR *dir;
    dir=opendir(path);
    while((ptr=readdir(dir))!=NULL)
    {
        //跳过'.'和'..'两个目录
        if(ptr->d_name[0] == '.')
            continue;
        fileNames.push_back(ptr->d_name);
    }
    closedir(dir);
    return fileNames;
}

这个方法是适用于Linux下的文件操作,在Windows上测试会报头文件找不到。如果真的要使用的话需要去下载这个头文件,并放入VS的include文件夹下即可。
下载地址
dirent.h

2.filesystem库(和上一个相比,这个就和谐多了,是可移植的)

2.1 获取文件的一些属性

//注意 /= 和 += 的区别, /= 表示追加下级目录, +=  仅仅是字符串的串接 
    path dir("C:\\Windows");
    dir /= "System32";       //追加下级目录
    dir /= "services.exe";
    std::cout << dir << std::endl;
    std::cout << dir.string() << std::endl;            //转换成std::string 类型
    std::cout << dir.root_name()<< std::endl;          //盘符名:C:
    std::cout << dir.root_directory()<< std::endl;     //根目录:"\"
    std::cout << dir.root_path()<< std::endl;          //根路径:"C:\"
    std::cout << dir.relative_path()<< std::endl;      // 相对路径:Windows\System32\services.exe
    std::cout << dir.parent_path()<< std::endl;        //上级目录:C:\Windows\System32
    std::cout << dir.filename()<< std::endl;           //文件名:services.exe
    std::cout << dir.stem()<< std::endl;               //不带扩展的文件名:services
    std::cout << dir.extension()<< std::endl;          //扩展名:.exe
    boost::filesystem::exists(file_path); //推断文件存在性

2.2文件的一些操作

#include "boost/filesystem.hpp"
#include <iostream>
#include <string>
//using namespace std;


int main(int argc, char *argv[])
{
    std::string file_path = "/media/data_2/everyday/0902/test1";
    if(boost::filesystem::exists(file_path))  //推断文件存在性
    {
        std::cout<<"file is exist"<<std::endl;
    }
    else
    {
        //文件夹不存在;
        boost::filesystem::create_directory(file_path);  //文件夹不存在。创建
    }

    std::string srcPath = "/media/data_2/everyday/0902/test.txt";
    std::string destPath = "/media/data_2/everyday/0902/test1/1112.txt"; //需要具体到文件名,要不然报错
    boost::filesystem::copy_file(srcPath , destPath);

    //获取文件名
    std::string srcPath = "/media/data_2/everyday/0902/test.txt";
    boost::filesystem::path path_file(srcPath);
    std::string file_name = path_file.filename().string();
    std::cout<<file_name<<std::endl;// test.txt

    return 1;
}

获取文件夹下所有文件名

#include "boost/filesystem.hpp"
#include <iostream>
#include <string>
//using namespace std;


int main(int argc, char *argv[])
{
    boost::filesystem::path path("/media/data_2/everyday/0902/test2");   //初始化
    boost::filesystem::path old_cpath = boost::filesystem::current_path(); //取得当前程序所在文件夹
    boost::filesystem::path parent_path = old_cpath.parent_path();//取old_cpath的上一层父文件夹路径
    boost::filesystem::path file_path = old_cpath / "file"; //path支持重载/运算符
    if(boost::filesystem::exists(file_path))  //推断文件存在性
    {
        std::string strPath = file_path.string();
        int x = 1;
    }
    else
    {
        //文件夹不存在;
        boost::filesystem::create_directory(file_path);  //文件夹不存在。创建
    }
    bool bIsDirectory = boost::filesystem::is_directory(file_path); //推断file_path是否为文件夹
    boost::filesystem::recursive_directory_iterator beg_iter(file_path);
    boost::filesystem::recursive_directory_iterator end_iter;
    for (; beg_iter != end_iter; ++beg_iter)
    {
        if (boost::filesystem::is_directory(*beg_iter))
        {
            continue;
        }
        else
        {
            std::string strPath = beg_iter->path().string();  //遍历出来的文件名称
            int x=1;
        }
    }
    boost::filesystem::path new_file_path = file_path / "test.txt";
    if(boost::filesystem::is_regular_file(new_file_path))   //推断是否为普通文件
    {
        int sizefile = boost::filesystem::file_size(new_file_path);  //文件大小(字节)
        int x =1;
    }
    boost::filesystem::remove(new_file_path);//删除文件new_file_path

    return 1;
}

其他一些操作

//字符串和string类型作为参数,而提供的路径可以是相对路径,也可以是绝对路径。
boost::filesystem::path filePath(file);
//path的方法如filename()等,返回的对象仍是path,path的string()方法,获取string类型
//parent_path()获得的是当前文件的父路径
cout<<filePath.parent_path()<<endl;  // "/home/test/cur/"

//filename()获得的是文件名,含拓展名
cout<<filePath.filename()<<endl;  // "build.sh"
cout<<filePath.filename().string()<<endl;

//stem()获得的是文件的净文件名,即不含拓展名
cout<<filePath.stem()<<endl; // "build"

//拓展名(是".sh"而不是"sh")
cout<<filePath.extension()<<endl; // ".sh"

//获得文件的大小,单位为字节
int nFileSize = boost::filesystem::file_size(filePath);

//最后一次修改文件的时间
//last_write_time()返回的是最后一次文件修改的绝对秒数
//last_write_time(filePath,time(NULL))还可以修改文件的最后修改时间,相当于Linux中命令的touch
if(filePath.last_write_time() - time(NULL) > 5)
{
    /*
     *在工程实践中,当需要不断的扫目录,而目录又会不断的加入新文件时,
     *借助last_write_time()可以判断新入文件的完整性,以避免处理未写完的文件
     */
}

//判断文件的状态信息
if(boost::filesystem::is_regular_file(file))
{
    //is_regular_file(file)普通文件
    //is_directory(file)目录文件,如当遍历到"/home/test/cur/src/"时,这就是一个目录文件
    //is_symlink(file)链接文件
    ...
}

//更改拓展名
boost::filesystem::path tmpPath = filePath;
//假设遍历到了cpp文件,想看下对应的.o文件是否存在
tmpPath.replace_extension(".o");
//判断文件是否存在
if( boost::filesystem::exists( tmpPath.string() ) )

//删除文件
//remove只能删除普通文件,而不能删除目录
boost::filesystem::remove(tmpPath.string());
//remove_all则提供了递归删除的功能,可以删除目录
boost::filesystem::remove_all(tmpPath.string());

//移动文件 & 拷贝文件
//srcPath原路径,srcPath的类型为string
//destPath目标路径,destPath的类型为string
boost::filesystem::rename(srcPath , destPath);
boost::filesystem::copy_file(srcPath , destPath);
//拷贝目录
boost::filesystem::copy_files("/home/test","/dev/shm")

获取目录下所有文件名

#include <boost/filesystem.hpp>
namespace fs = boost::filesystem;
 
int get_filenames(const std::string& dir, std::vector<std::string>& filenames)
{
    fs::path path(dir);
    if (!fs::exists(path))
    {
        return -1;
    }
 
    fs::directory_iterator end_iter;
    for (fs::directory_iterator iter(path); iter!=end_iter; ++iter)
    {
        if (fs::is_regular_file(iter->status()))
        {
            filenames.push_back(iter->path().string());
        }
 
        if (fs::is_directory(iter->status()))
        {
            get_filenames(iter->path().string(), filenames);
        }
    }
 
    return filenames.size();
}
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值