在单位也是实习了快有一有点时间了,但是最近总觉得最近进入到了某种呆滞的状态,借用孔夫子的话来说,学而不思则罔,思而不学则殆。当下午临时要做一个小工具,批量修改文件夹的文件名,一直不停的百度,就想总结下这方面的技能,开始我的第一篇博客吧。
1. 目标:实现批量修改文件名
例如:文件夹X中有文件 a_1.txt,a_2.txt,修改成a20161209_1.txt,a20121209_2.txt
2. 功能点分析:
a,读取文件夹目录,遍历文件夹下的文件名称
b,进行字符串解析,并且替换文件名
c,将修改的文件名称替换原来的文件的名字
3. 功能实现
【这里将使用的是C++11】那么这里可以使用两种技术来实现:
-------------------------------
a,创建一个MFC工程
b,创建一个控制台程序
-------------------------------
相对而言,我认为使用那种技术来实现思路都是差不多的,值得斟酌的就是*MFC - CString* 和 *C++ - string* 之间的较量,以及*CFileDialog*和C++通过调用*windowAPI* 遍历文件夹下的文件。
好按照功能点分析,第一步先获取文件夹下的所有文件,如果用c++ 操作,这里需要思考的有俩个点。1,如何获取需要读取的目录地址 2,如果获取该目录下的所有文件路径。我们分别使用C++ 和 MFC的代码来进行描述。
func1_1 – 如何获取需要读取的目录地址
//C++ 如何获取需要读取的目录地址【以下部分摘自他人】
// 我的思路是优先获取当前程序的路径,然后在同目录下添加配置文件,读取路径
char buf[256];
//typedef HINSTANCE HMODULE;
/* HMODULEs can be used in place of HINSTANCEs
这个句柄不理解,有空请教下学习学习
【暂且标记一波,HANDLES 和 HMODULES 的区别】
*/
//GetModuleHandle(0) : 如果说为空的话,得到的就是当前所调用该函数的程序实例句柄
HMODULE module = GetModuleHandle(0);
CHAR buff[MAX_PATH];
//获取当前进程已加载模块的文件的完整路径,该模块必须由当前进程加载。
GetModuleFileName(module, buff, sizeof(buff));
/*
如果说路径是C:\Users\xxx\Desktop\pic_CSDN\xxx.png
那么就需要将\xxx.png去除,所以先要找到 "\\" 的位置,然后通过字符串获取到 "\\" 之前的路径
*/
string route = buff;
int n = route.find_last_of("\\");
string halfRoute = route.substr(0,n);
// 加上cfg.ini 那么就是配置文件的路径,然后读取配置文件,获取读取文件路径
halfRoute += "\\cfg.ini";
//至于文件的读取方式:
//1.[ini文件的读写](http://blog.csdn.net/zhouqt/article/details/53457845)
//2.[tinyxml2读取配置文件]
//3.[c++ 通过ofstream 流进行读写]
//以后希望整理一篇这样的文章,参考些大神的资料
func1_2 – 如果获取该目录下的所有文件路径
//C++ 获取文件夹下文件的路径【以下部分摘自他人】
vector<string> getFiles(string cate_dir)
{
vector<string> files;//存放文件名
_finddata_t file;
/** _finddata_t 结构体的定义
#define _finddata_t _finddata64i32_t
struct _finddata64i32_t {
unsigned attrib; /*文件属性*/
__time64_t time_create; /* -1 for FAT file systems */
__time64_t time_access; /* -1 for FAT file systems */
__time64_t time_write;
_fsize_t size;
char name[260];
};
*/
long lf;
/*
long _findfirst( char *filespec, struct _finddata_t *fileinfo );
findfirst,搜索与指定的文件名称匹配的第一个实例,若成功则返回第一个实例的句柄,否则返回-1L。
char *filespec : 访问文件的路径
struct _finddata_t *fileinfo : 引用,获取文件的_finddata_t结构体
*/
if ((lf=_findfirst(cate_dir.c_str(), &file)) == -1)
{
}
else
{
/**
用法和_findfirst的用法差不多
int _findnext(
intptr_t handle,
struct _finddata_t *fileinfo
);
handle : 之前在 _findfirst 返回获取的文件句柄
struct _finddata_t *fileinfo : 引用,获取文件的_finddata_t结构体
*/
while(_findnext(lf, &file) == 0)
{
//去除 . \ .. 这两种目录
if (strcmp(file.name, ".") == 0 || strcmp(file.name, "..") == 0)
continue;
// 将文件名称放到files 集合中
files.push_back(file.name);
}
}
// 这个不是特别理解,但是猜测应该和文件 open \ close 类似,应该是中安全保障机制
_findclose(lf);
return files;
}
func2_1 – MFC 获取【相对方便】
//MFC 获取文件夹下文件的路径【以下部分摘自他人】
// 可以从源码看到这样一个构造函数的结构
explicit CFileDialog(BOOL bOpenFileDialog, // TRUE for FileOpen, FALSE for FileSaveAs
LPCTSTR lpszDefExt = NULL, // 文件的扩展名
LPCTSTR lpszFileName = NULL, // 默认文件名
DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, // 风格
LPCTSTR lpszFilter = NULL, // 打开的文件类型
CWnd* pParentWnd = NULL,
DWORD dwSize = 0,
BOOL bVistaStyle = TRUE);
virtual ~CFileDialog();
[**这里学习了下这位大神写的**](http://blog.sina.com.cn/s/blog_45eaa01a0102uzlq.html)
CFileDialog fileDlg(TRUE, // TRUE打开,FALSE保存文件对话框
".csv", // 默认的打开文件的类型
NULL, // 默认打开的文件名
OFN_ALLOWMULTISELECT|OFN_ENABLESIZING|OFN_HIDEREADONLY | OFN_NOCHANGEDIR, // 多选打开
"Excel文件(*.csv)|*.csv|所有文件(*.*) |*.*||" // 打开的文件类型
);
fileDlg.m_ofn.lpstrTitle="选择多个文件";
// 设置默认路径
fileDlg.m_ofn.lpstrInitialDir=strPath.GetBuffer(0);
// 调用对话框,获取
if (IDOK==fileDlg.DoModal())
{
CString pathName;
//struct __POSITION {};
//typedef __POSITION* POSITION;
[__POSITION的解释 ](http://blog.csdn.net/l_andy/article/details/17509865)
POSITION pos_file;
/*
_AFXDLGS_INLINE POSITION CFileDialog::GetStartPosition() const
{ return (POSITION)m_ofn.lpstrFile; }
一路查询m_ofn,查询到这个结构体
typedef struct tagOFNW {
DWORD lStructSize;
HWND hwndOwner;
HINSTANCE hInstance;
LPCWSTR lpstrFilter;
LPWSTR lpstrCustomFilter;
DWORD nMaxCustFilter;
DWORD nFilterIndex;
LPWSTR lpstrFile;
DWORD nMaxFile;
LPWSTR lpstrFileTitle;
DWORD nMaxFileTitle;
LPCWSTR lpstrInitialDir;
LPCWSTR lpstrTitle;
DWORD Flags;
WORD nFileOffset;
WORD nFileExtension;
LPCWSTR lpstrDefExt;
LPARAM lCustData;
LPOFNHOOKPROC lpfnHook;
LPCWSTR lpTemplateName;
#ifdef _MAC
LPEDITMENU lpEditInfo;
LPCSTR lpstrPrompt;
#endif
#if (_WIN32_WINNT >= 0x0500)
void * pvReserved;
DWORD dwReserved;
DWORD FlagsEx;
#endif // (_WIN32_WINNT >= 0x0500)
} OPENFILENAMEW, *LPOPENFILENAMEW;
老长一串儿,结果一查 : OPENFILENAME结构包含了GetOpenFileName和GetSaveFileName函数用来初始化打开或另存为对话框的信息。在用户关闭对话框后,系统返回关于用户的选择信息到这个结构中。
*/
pos_file = fileDlg.GetStartPosition();
strFiles="";
while(NULL!=pos_file)
{
//循环读出每个文件路径和名称
pathName=fileDlg.GetNextPathName(pos_file);
strFiles+=pathName+split;//"|";
}
}
}