(Window和linux下)c/c++如何遍历文件夹中的文件及子文件夹并改写文件名

(Window和linux下)c/c++如何遍历文件夹中的文件及子文件夹并改写文件名

Window

#include <iostream>
#include <string>
#include <io.h>

using namespace std;

//便于跨平台
#ifdef WIN32
    #define oldname "C:\\Users\\TuZhou\\Desktop\\featurelib\\images"
    #define newname "C:\\Users\\TuZhou\\Desktop\\featurelib\\images"

#else
    #define oldname "/home/share_linux/featurelib/images/"
    #define newname "/home/share_linux/featurelib/images/"

#endif

void findfile(string path, string mode)
{
    _finddata_t file;         
    intptr_t HANDLE;
    string Onepath = path + mode;
    HANDLE = _findfirst(Onepath.c_str(), &file);
    if (HANDLE == -1L)
    {
        cout << "can not match the folder path" << endl;
        system("pause");
    }
    
    cout << "success open file" << endl;
    //int i = 1;
    do {         	
    	    //判断是否为"."当前目录,".."上一层目录
            if ((strcmp(file.name, ".") == 0) || (strcmp(file.name, "..") == 0))
            {
                continue;
            }
               
	        //判断是否有子目录  
	        if (file.attrib & _A_SUBDIR)
	        {
	            string newPath = path + "\\" + file.name;
	            //cout << newPath << endl;
	            findfile(newPath,mode);
	        }
	        
	        else
	        {
	            cout << file.name << " " << endl;
	            // string s = oldname;
	            // s = s + file.name;
	            //strcat(s, file.name);
	            //string id =path + to_string(i++) + ".jpg";
	            //rename(s.c_str(), id.c_str());
	        }
	    } while (_findnext(HANDLE, &file) == 0);
	
	    _findclose(HANDLE);
}


int main(int argc, char **argv)
{
	string mode = "\\*.*";
	string path = oldname;
	findfile(path,mode); 
	return 0;
}

其中#ifdef WIN32是便于跨平台使用,此处可以不加,不过也只是记录一下,如果是64位系统也没问题,毕竟64位可以向32位兼容,64位win也可以写成#ifdef WIN64但是若是32位系统就无法使用。

核心部分使用c++中的_finddata_t 结构体,必须要加上io.h头文件。
关于_finddata_t 中的attrib为读取到文件的属性,该值和_A_SUBDIR进行&操作的结果为真的话,代表读取到的是个文件夹,此时就递归进入文件夹里继续读取。
详细可参考_finddata_t结构体等描述

更改文件名很简单,直接使用一个函数就行

rename(oldName.c_str(), newName.c_str())
参数均为const char*类型,可用string定义使用c_str()函数转换。
参考自c++修改文件名

main函数中的string mode = "\\*.*"
其中*.*为文件路径中的通配符,*代表0个或多个任意字符,.*表示的是该目录下所有类型文件和目录以及”.”".."
注意_findfirst打开的路径必须是要加上这个通配符的,否则你打开读取的文件名还是该文件夹本身,容易无限读取。
详细可参考
文件目录通配符
路径通配符

linux

老规矩先贴代码

#include <iostream>
#include <stdio.h>
#include <unistd.h>
#include <dirent.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <string.h>

using namespace std;

#define images_dir "./images"
/***** Global Variables *****/
/* Show all files under dir_name , do not show directories ! */

void showAllFiles( string  dir_name )
{
	// check the parameter !
	if(dir_name.empty())
	{
		cout<<" dir_name is null ! "<<endl;
		return;
	}

	// check if dir_name is a valid dir
	struct stat s;
	lstat( dir_name.c_str() , &s );
	if( ! S_ISDIR( s.st_mode ) )
	{
		cout<<"dir_name is not a valid directory !"<<endl;
		return;
	}

	struct dirent * filename;    // return value for readdir()
 	DIR * dir;                   // return value for opendir()
	dir = opendir( dir_name.c_str() );
	if( NULL == dir )
	{
		cout<<"Can not open dir "<<dir_name<<endl;
		return;
	}

	//cout<<"Successfully opened the dir !"<<endl;
	
	/* read all the files in the dir ~ */
	int face_index = 1;
	while( ( filename = readdir(dir) ) != NULL )
	{
		//get rid of "." and ".."
		if( strcmp( filename->d_name , "." ) == 0 || 
			strcmp( filename->d_name , "..") == 0  )
			continue;

		if(filename->d_type == 4)
		{
			//cout << filename->d_name << endl;
			showAllFiles(dir_name + "/" + filename->d_name + "/");
		}

		else
			cout<<filename ->d_name <<endl;
	}
} 


int main()
{
	string dir = images_dir;
	// 测试
	showAllFiles( dir );
	return 0;
}

请注意,无论是window下和linux下的文件遍历代码,在while循环中我都加了这么一个判断:
if( strcmp( filename->d_name , "." ) == 0 || strcmp( filename->d_name , "..") == 0 )
这个是判断当前读取到的文件名是否是"."或者是"..",前者代表的是当前目录,后者代表的是上一目录,每个文件夹中都包含有这两个隐藏目录,就像一个是文件夹的入口,一个是文件夹的出口。当读取文件夹时会先读取到这两个隐藏目录,所以遇到直接continue。

在linux下使用的文件方法与window下不同,关于stat,dirent等类型的解释可参考:
stat方法类型
dirent及文件操作方法
DIR目录流类型

更改文件名同样可使用rename函数。

在while循环中的这段代码:
if(filename->d_type == 4)这里d_type为代表读取到的文件属性,当其为4时代表读到的是个文件夹,所以进入递归继续往里读。
关于dirent的d_type属性更多介绍请参考:
d_type属性

暂记到此,如有过错,敬请批正。

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
要将Windows文件夹下的OS文件存入Linux系统,可以通过以下几种方式: 1. 使用命令行,将OS文件复制到Linux系统的目录,例如: ``` scp /path/to/your/file <user>@<IP address>:/path/to/destination ``` 其,`<user>`是Linux系统的用户名,`<IP address>`是Linux系统的IP地址,`/path/to/destination`是Linux系统存储OS文件的目录路径。 2. 在Linux系统使用FTP等工具,将OS文件上传到Linux系统指定的目录。 3. 如果Windows和Linux系统在同一网络,可以在Linux系统访问Windows共享文件夹,并将OS文件复制到Linux系统的目录。例如: ``` mount -t cifs //<Windows IP address>/<Windows shared folder> /mnt -o user=<Windows username>,password=<Windows password> cp /mnt/<path to your file> /path/to/destination ``` 其,`<Windows IP address>`是Windows系统的IP地址,`<Windows shared folder>`是Windows共享文件夹的名称,`<Windows username>`和`<Windows password>`是登录Windows系统的用户名和密码,`/mnt`是Linux系统挂载Windows共享文件夹的目录路径,`<path to your file>`是Windows系统存储OS文件的路径,`/path/to/destination`是Linux系统存储OS文件的目录路径。 需要注意的是,Windows和Linux系统的文件系统不同,因此需要在Linux系统选择正确的文件系统类型,例如,如果Windows系统使用NTFS文件系统,需要在Linux系统使用NTFS模块来挂载Windows共享文件夹

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值