文件操作:c++、python

要进行训练,那样本的读取和分类就是需要搞定的了。这篇文字主要记录c++、python的文件操作,包含文件夹的遍历、文件的读取判断等。不定期更新。

5.9:c++如何进行文件夹的遍历

看了一些文章,说包含 io.h 就能进行相关操作了,可是我ubuntu怎么都找不到 io.h。
于是想了一个办法,我要进行人脸识别,每次录入样本后会单独存在一个文件夹里,然后训练之前要生成样本的描述文件。
我是这样解决的,录入样本,记录样本文件夹名字在一个txt文件中,然后新一次录入和前面的对比,不一样则标签定位在文件末尾,标签加一。生成描述文件时,先读取txt文件中的名字,存在一个vector中,然后再进行每个文件夹的读取。
用到的c++文件操作有:

进行文件每行信息的提取,对比,不一样的样本名存在末尾

  1. 以读取打开文件
  2. 逐行读取,并每行进行分割,分出标签和名字
  3. 替换或者定位到末尾。
#include <iostream>
#include <fstream>
#include <sstream>
#include <dirent.h>

bool save_samplename(string name){
    char separator = ' ';
    string line, old_name, classlabel;
    fstream f;
    f.open(names_file,ifstream::in);
    if(!f){
        ofstream fc(names_file,ofstream::out);
        fc.close();
        f.open(names_file,ifstream::in);
    }
    int last_label = -1;
    while (!f.eof()) {
        getline(f, line);
        //cout << line << endl;
        stringstream lines(line);
        getline(lines, old_name, separator);//获取样本名字
        getline(lines, classlabel);	//获取标签
        if(name == old_name)
            return 0;
        if(!classlabel.empty())
            last_label = atoi(classlabel.c_str());
        else if(!old_name.empty())
            break;
    }
    f.close();

    ofstream fo;                    	//写打开
    fo.open(names_file,ofstream::app);   //定位到文章末尾
    last_label ++;
    fo<<name<<separator<<last_label<<endl;
    fo.close();
    return 1;
}
  1. 介绍一下该txt文件的读取与分割,其格式为  
    youj 0
    xiaom 1
  2. 先以读取打开文件
  3. 然后进行逐行读取
  4. 再利用 ccstream 进行行分割(空格)读取
         getline(f, line);
        //cout << line <<endl;
        if(line.empty())
            break;
        //lines.push_back(line.c_str());
        stringstream lines(line);
        getline(lines, old_name, separator);//获取样本名字
        getline(lines, classlabel);			//获取标签
        name.push_back(old_name.c_str());
        label.push_back(atoi(classlabel.c_str()));

进行母文件夹中找知道名字的子文件夹,并遍历该子文件夹 包含 dirent.h
并生成csv描述文件

  1. 读取txt文件中的名字(即子文件夹)和标签
  2. 打开子文件夹,利用dir = opendir(m[i].c_str());
  3. 遍历,while((ptr = readdir(dir)) != NULL) //循环读取目录下数据
  4. 输出遍历的文件名,filename = ptr->d_name; //输出文件名
void get_namescsv()
{
    DIR *dir;
    struct dirent * ptr;
    string rootdirPath = mum_path;
    string filename;
    vector<string> m;
    vector<int> l;
    read_names(m,l);
    ofstream csv;
    csv.open(listpath,ofstream::out);
    for(int i = 0;i < m.size();i++){
        m[i] =  mum_path+"/"+ m[i];
        cout << m[i].c_str() << "  "<<l[i]<<endl;
        dir = opendir(m[i].c_str());
        while((ptr = readdir(dir)) != NULL)//(为什么这个遍历机制不会在扫描完成之前重复扫描)!!!很好用
        {
            filename = ptr->d_name; 		//输出文件名
            if(filename[0] == '.')			//过滤隐藏文件
                continue;
            csv << m[i]+"/"+filename +" "<<l[i]<<endl;
        }
    }
    csv.close();
}

python进行文件夹的遍历并生成描述文件##

python进行文件操作就非常简单容易了,下面介绍两种方式

方式一:

  1. os.listdir列出所有子文件夹,注意列出的是文件夹名,后面需要加 ‘/’
  2. os.listdir(path)列出子文件夹中的文件
  3. 可以在第二步前加上判断是否是文件夹,if os.path.isdir(file_img):
import sys
import os
DataPath = "face/"   				#/home/jiang/Repositories/人脸识别/cv-face_predict/face
datalistname = "train.csv"
dirList = os.listdir(DataPath)                                        #列出文件夹的所有文件
if os.path.exists(DataPath+datalistname):
	print "err please delete"
	#os.remove(os.path.join(DataPath, datalistname))
	os.remove("face/train.csv")
for name in dirList:
	path = DataPath + str(name) + '/'
	print path
	cpath = str(path)[16:str(path).rfind('/')+1]
	f = open(DataPath+datalistname,'a+')
	fileList = os.listdir(path)
	for fileName in fileList:
		print fileName
		f.write(cpath + fileName + ';' + '\n')

方式二

  1. 直接粗暴方式for root, dirs, files in os.walk(mum_path):
  2. 分别返回 母文件夹名、所有文件夹名、所有文件名
  3. 文件名拼接 filepath = os.path.join(root,filename)
for root, dirs, files in os.walk("./train"):                  # os.path.basename("/etc/sysconfig/selinux")   'selinux'          
        #print   dirs         
	for filename in files:
                root_int = root.split('/')[2]                 #文件夹的名字,即标签 0-9  
	       		filepath = os.path.join(root,filename)
                #print filepath
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值