1、C++批量修改指定文件夹下所有文件
1)分别从C++与Python语言实现文件名字修改作比较,充分体现Python语言的简介性。
2)代码主要修改指定文件夹下所有文件的文件名。
3)文件夹下的文件可以筛选,选出不想修改的文件格式,不做修改,其余的文件全部修改。
4)此处代码中只是实现了对筛选出的文件的后缀名的添加,也可以将文件名字按序增加修改,或者按照指定规律修改文件名字。
C++修改文件名:
/**改变文件后缀名
1、GetAllFormatFiles(filepath, files);读出文件夹内的所有文件,
2、通过对获取的所有文件进行筛选,continue方式排除带有".JPG"".xml"两种文件格式的文件
3、为剩余的文件添加后缀名,此处为".xml"
ps:必须是64位的调试方式*/
#include<iostream>
#include<fstream>
#include<string>
#include<vector>
#include<io.h>
#include <direct.h>
#include <cstdlib>
using namespace std;
//using namespace cv;
/*获取特定格式的文件名
该函数有两个参数,第一个为路径字符串(string类型,最好为绝对路径);
第二个参数为文件夹与文件名称存储变量(vector类型,引用传递)。
第三个直接使用".bmp"即可
*/
void GetAllFormatFiles(string path, vector& files)
{
//文件句柄,通过对_findnexti64的查找,第一个参数是_int64型,因此写int就会报错
_int64 hFile = 0;
//文件信息
struct _finddatai64_t fileinfo;
string p;
if ((hFile = _findfirsti64(p.assign(path).append("\\*").c_str(), &fileinfo)) != -1)
{
do
{
if ((fileinfo.attrib & _A_SUBDIR))
{
if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0)
{
//files.push_back(p.assign(path).append("\\").append(fileinfo.name) );
GetAllFormatFiles(p.assign(path).append("\\").append(fileinfo.name), files);
}
}
else
{
files.push_back(p.assign(fileinfo.name)); //将文件路径保存,也可以只保存文件名: p.assign(path).append("\\").append(fileinfo.name)
}
cout << "?" << endl;
} while (_findnexti64(hFile, &fileinfo) == 0);
_findclose(hFile);
}
}
int main(int argc, char* argv[])
{
string filepath = "E:/VC_Code/数据集/输电线路标注/testXML";
cout << "filepath=" << filepath << endl;
vector files;
string Nsfile;
GetAllFormatFiles(filepath, files);
char * distAll = "AllFiles.txt";
ofstream ofn(distAll);
int size = files.size();
for (int i = 0; i < size; i++)
{
ofn << files[i] << endl;
}
ofn.close();
string temp, temp1, temp2;
for (int i = 0; i < size; i++)
{
temp = filepath + "/" + files[i];//带有图片位置的字符串
cout << filepath << endl;
cout << files[i] << endl;
cout << temp << endl;
char cstr[37];
strcpy(cstr, temp.c_str());
cout << "temp=" << temp << '\n' << "cstr=" << cstr << '\n' << "size(cstr)=" << sizeof(cstr) << endl;
Nsfile = files[i].c_str();
//排除".JPG"".xml"后缀文件
int pos1 = Nsfile.find(".jpg");
int pos2 = Nsfile.find(".xml");
if (pos1 > -1 || pos2 > -1)
{
//Nsfile.erase(pos, 4);
continue;
}
cout << "Nsfile=" << Nsfile << endl;
Nsfile = files[i] + ".xml";
temp1 = filepath + "/" + Nsfile;
cout << "temp1=" << temp1 << endl;
if (!rename(temp.c_str(), temp1.c_str()))
{
std::cout << "rename success " << std::endl;
}
else
{
std::cout << "rename error " << std::endl;
}
}
system("pause");
return 0;
}
5)上述代码中,通过函数GetAllFormatFiles(filepath, files)读出文件夹内的所有文件。
这里另外添加一个获取文件夹下指定后缀名的所有文件,需要头文件#include <glob.h>。以".jpg"后缀名的文件为例:
vector<string> globVector(const string& pattern){
glob_t glob_result;
glob(pattern.c_str(),GLOB_TILDE,NULL,&glob_result);
vector<string> files;
for(unsigned int i=0;i<glob_result.gl_pathc;++i){
files.push_back(string(glob_result.gl_pathv[i]));
}
globfree(&glob_result);
return files;
}
调用方式:
const string& imagePath = "$图像输入路径/*.jpg";
vector<string> files = globVector(imagePath);//获取目录imagePath下所有*.jpg文件,存储到vector中
for (int i=0;i<files.size();i++)
{
cout<<files[i]<<endl;
}
2、Python修改文件名:
import os
'''
#读取文件夹下指定格式文件
将文件夹中的'.JPG'与'.xml'(还可以根据需要加入其他格式)文件筛选出来,不予处理,其他文件加入'.xml'(或其他后缀名)
'''
def getFormatFile(filepath,*unchangeFileFormat):
pathDir=os.listdir(filepath)
total_num=len(pathDir)
i=0
for item in pathDir:
x=os.path.splitext(item)[1]
print('x=',x)
if x in unchangeFileFormat:
continue
else:
src=os.path.join(os.path.abspath(filepath),item)
dst=os.path.join(os.path.abspath(filepath),item+'.xml')
print('src=',src)
print('dst=',dst)
os.rename(src,dst)
print('i=',i)
i+=1
continue
print('total %d rename %d xml'%(total_num,i))
return
file_path='E:/Code/Test2_Python/test_pic'
unchange_file_format1='.JPG'
unchange_file_format2='.xml'
getFormatFile(file_path,unchange_file_format1,unchange_file_format2)
增加一个代码:
import os
import shutil#复制需要的包
def renameXML(inputPath,outputPath,i):
imgorder=i
XMLorder=i
for _,dirs,files in os.walk(inputPath):
for f1 in files:
if (os.path.splitext(f1)[1]== '.JPG') \
or (os.path.splitext(f1)[1]== '.jpg'):
#print(os.path.splitext(f1)[1])
imgnewname=str(imgorder).zfill(6)+'.jpg'#固定新文件名长度
shutil.copy(os.path.join(inputPath,f1),os.path.join(outputPath,imgnewname))#复制图片,顺便把名字也改了
#os.rename(os.path.join(outputPath,f1),os.path.join(outputPath,imgnewname))#改图片文件名,这个函数会删除原文件
imgorder = imgorder + 1
for f2 in files:
if (os.path.splitext(f2)[1]=='.xml')\
and (os.path.splitext(f1)[0] == os.path.splitext(f2)[0]):
XMLnewname = str(XMLorder).zfill(6) + '.xml' # 固定新文件名长度
shutil.copy(os.path.join(inputPath, f2), os.path.join(outputPath, XMLnewname))
#os.rename(os.path.join(outputPath, f2), os.path.join(outputPath, XMLnewname))#改xml文件名
XMLorder = XMLorder + 1
print('xml的数量:'+str(XMLorder-1))
print('jpg和JPG的数量:' + str(imgorder - 1))
def changeXMLcontent(XMLpath):#此处仅仅修改“<filename>”行,改一下文件名
for _, dirs, files in os.walk(XMLpath):
for f1 in files:
if (os.path.splitext(f1)[1]=='.xml'):
with open(os.path.join(XMLpath,f1),'r',encoding="utf-8") as f_r:
lines = f_r.readlines()
with open(os.path.join(XMLpath, f1), 'w', encoding="utf-8") as f_w:
for line in lines:
if '<filename>' in line:
line=' <filename>'+os.path.splitext(f1)[0]+'</filename>\n'
print(line)
f_w.write(line)
if __name__=='__main__':
inputpath="F:/code of deal with xml/test"
outputpath="F:/code of deal with xml/output"
renameXML(inputpath,outputpath,1)
changeXMLcontent(outputpath)
增加一个用xml.etree.ElementTree修改xml文件的代码。
参考网站:https://docs.python.org/3/library/xml.etree.elementtree.html#
import xml.etree.ElementTree as ET
def xmlFilesContent(xmlFilesPath):
for _,dirs,files in os.walk(xmlFilesPath):
for f in files:
if os.path.splitext(f)[1]=='.xml':
tree = ET.parse(os.path.join(_,f))
root = tree.getroot()
for child in root:
if child.tag=='filename':
child.text = os.path.splitext(f)[0]+'.jpg'
tree.write(os.path.join(_,f))
ps:如果xml文件不是按照xml.etree.ElementTree规则写的,可能会遇到某些元素Element不存在的情况。这种情况下,建议直接采用“一行一行读取并修改”。