如何实现对一个文件夹下的所有文件(包括子文件夹下的所有文件)改名?

时间:2021-04-26 09:55:01
请给出源码,谢谢!解决问题的话,另开贴子再给100分!

13 个解决方案

#1


VC的行不行?  你所说的改名要按什么条件来改?

#2


如何实现对一个文件夹下的所有文件(包括子文件夹下的所有文件)改名? 

首先,要枚举磁盘某个目录下的文件,再改名代码如下:
 (用 CFindFileDlg的SearchFile函数实现):

void Rename_File(CString strDir)
{
 CFileFind ff;
 CString szDir = strDir;
 
 if(szDir.Right(1) != "\\")
  szDir += "\\";
 
 szDir += "*.*";
 
 BOOL res = ff.FindFile(szDir);
 while(res)
 {
  res = ff.FindNextFile();
  
  
  if(ff.IsDirectory() && !ff.IsDots())//目录是文件夹
  {
   //如果是一个子目录,用递归继续往深一层找
   
   CString strPath = ff.GetFilePath(); 
              //得到路径,做为递归调用的开始
   CString strTitle = ff.GetFileName();
            //得到目录名

   SearchFile(strPath);//递归调用
  }
  else if(!ff.IsDirectory() && !ff.IsDots())//到达最低层的文件
  {
   CString strPath;
   CString strTitle;
   strPath = ff.GetFilePath();
   strTitle = ff.GetFileName();
   //这里用标准C的rename()或者是API的MoveFile来将文件改名,不知道楼主要用什么改名.
   //所以就不写了......

  }
 }
 ff.Close();//关闭
}
调用方法:Rename_File(欲改名的路径)


附rename()的调用实例:
void main( void )
{
   int  result;
   char old[] = "RENAMER.OBJ", new[] = "RENAMER.JBO";

   /* Attempt to rename file: */
   result = rename( old, new );
   if( result != 0 )
      printf( "Could not rename '%s'\n", old );
   else
      printf( "File '%s' renamed to '%s'\n", old, new );
}

#3


上面的代码贴出来时,作了一些修改,还有一两处没改到,不好意思,重发:

void Rename_File(CString strDir)
{
 CFileFind ff;
 CString szDir = strDir;
 
 if(szDir.Right(1) != "\\")
  szDir += "\\";
 
 szDir += "*.*";
 
 BOOL res = ff.FindFile(szDir);
 while(res)
 {
  res = ff.FindNextFile();
  
  
  if(ff.IsDirectory() && !ff.IsDots())//目录是文件夹
  {
   CString strPath = ff.GetFilePath(); 
   CString strTitle = ff.GetFileName();
   Rename_File(strPath);
  }
  else if(!ff.IsDirectory() && !ff.IsDots())
  {
   CString strPath;
   CString strTitle;
   strPath = ff.GetFilePath();
   strTitle = ff.GetFileName();
   //这里用标准C的rename()或者是API的MoveFile来将文件改名,不知道楼主要用什么改名.
   //所以就不写了......

  }
 }
 ff.Close();//关闭
}

#4


TO:zhouhuahai(道号"虚无") 
标准C语言或用C++Builder的都可以,VC我不会用啊。

#5


谢谢zhouhuahai的热心帮助。不过,你的代码应该也不行,与我用C++Builder代码做的类似,主要是文件改名后,还会再改!比如,abc.doc会改成abc.doc.eee.eee.eee.eee等。我的函数如下。

void __fastcall TForm1::RenameFiles(int flag)
//flag=1时,加上.eee后缀
//flag=2时,去除.eee后缀
{
  TSearchRec sr;
  AnsiString DestName;
  if(FindFirst("*.*",faAnyFile,sr)==0)
  {
    do
    {
      if((sr.Attr&faDirectory)&&(sr.Name!=".")&&(sr.Name!=".."))
     //如是子目录(不包括.和..子目录)
      {
        chdir(sr.Name.c_str());
        RenameFiles(flag); //调用递归函数
        chdir("..");
      }
      else if((sr.Name!=".")&&(sr.Name!=".."))
      {
        if(flag==1)
        {
//        ShowMessage(sr.Name);
          RenameFile(sr.Name,sr.Name+".eee");  //文件改名,加上.eee后缀
        }
        else
        {
          if(AnsiString(sr.Name).SubString(AnsiString(sr.Name).Length()-3,4).UpperCase()==".eee")
          {
            DestName=AnsiString(sr.Name).Delete(AnsiString(sr.Name).Length()-3,4);
          }
          RenameFile(sr.Name,DestName);   //文件改名,去除.eee后缀
        }
      }
    }while(FindNext(sr)==0);
  }
  FindClose(sr);
}

#6


这样不稳妥
如果你要把一个文件夹下的文件名字都改变成001,002,003,、、、、
这样的,而原来的实际的名字是 020,001,021。。。
那么按照搜索的机制,第一个020改成001就不成功,因为001已经在目录当中存在了

安全的做法是
先把已经有的文件的名字全部提取成一个列表当中,然后判别它是否可以这样做
对于那些已经存在名字是无需处理的

#7


“如果你要把一个文件夹下的文件名字都改变成001,002,003,、、、、
这样的,而原来的实际的名字是 020,001,021。。。
那么按照搜索的机制,第一个020改成001就不成功,因为001已经在目录当中存在了”
我不存在这个问题,因为我的改名只是将它加上.eee的后缀名。
不过你的“先把已经有的文件的名字全部提取成一个列表当中”提醒了我,可以先全部提取到一个列表中,等搜索完后,再改名,可能就可以了。谢谢!

#8


改名是否成功有多种因素的
1 同名文件或者文件夹存在不能
2 隐藏或者只读或者系统属性下不能改名
3 文件被打开状态不能改名
......

简单的写一个Find Rename结构不是具有普遍性的功能
需要有一个安全的机制来处理它

#9


如果要达到楼主的功能, 可以用一个string数组来保存找到的文件名.在查找结束后再统一进行改名.

#10


专业顶贴 兼职接分 ^_^

#11


以下是用C写的程序,把某目录下所有文件的头一个字母都改成大写A。

#include <stdio.h>
#include <dir.h>
#include <dos.h>
#include <stdlib.h>
#include <string.h>

void tracedir(char *);

int main(void)
{
char *cpRoute = "c:\\tcwin\\output\\test\\";
tracedir(cpRoute);
return 0;
}


void tracedir(char *cpDir)
{
char *cpOldName, *cpNewName, *cpDirectory, *cpTemp;
struct ffblk FFileStru;
int iReturnValue, iLength;
iLength = strlen(cpDir);
cpDirectory = (char*)malloc(iLength+4);
strcpy(cpDirectory, cpDir);
strcat(cpDirectory, "*.*");
iReturnValue = findfirst(cpDirectory, &FFileStru, 0);
while(!iReturnValue)
{
cpOldName = (char*)malloc(iLength+strlen(FFileStru.ff_name)+1);
strcpy(cpOldName, cpDir);
strcat(cpOldName, FFileStru.ff_name);
cpNewName = (char*)malloc(iLength+strlen(FFileStru.ff_name)+1);
*FFileStru.ff_name = 'A';
strcpy(cpNewName, cpDir);
strcat(cpNewName, FFileStru.ff_name);
rename(cpOldName, cpNewName);
free(cpOldName);
free(cpNewName);
iReturnValue = findnext(&FFileStru);
}
iReturnValue = findfirst(cpDirectory, &FFileStru, FA_DIREC);
while(!iReturnValue)
{
if(strcmp(FFileStru.ff_name, ".") && strcmp(FFileStru.ff_name, ".."))
{
cpTemp = (char*)malloc(iLength+strlen(FFileStru.ff_name)+3);
strcpy(cpTemp, cpDir);
strcat(cpTemp, FFileStru.ff_name);
strcat(cpTemp, "\\");
tracedir(cpTemp);
free(cpTemp);
}
iReturnValue = findnext(&FFileStru);
}
free(cpDirectory);
return;
}

#12


漏写了会遍历所有子目录。

#13


先判断,如果文件的扩展名是.eee就不要改了。

#1


VC的行不行?  你所说的改名要按什么条件来改?

#2


如何实现对一个文件夹下的所有文件(包括子文件夹下的所有文件)改名? 

首先,要枚举磁盘某个目录下的文件,再改名代码如下:
 (用 CFindFileDlg的SearchFile函数实现):

void Rename_File(CString strDir)
{
 CFileFind ff;
 CString szDir = strDir;
 
 if(szDir.Right(1) != "\\")
  szDir += "\\";
 
 szDir += "*.*";
 
 BOOL res = ff.FindFile(szDir);
 while(res)
 {
  res = ff.FindNextFile();
  
  
  if(ff.IsDirectory() && !ff.IsDots())//目录是文件夹
  {
   //如果是一个子目录,用递归继续往深一层找
   
   CString strPath = ff.GetFilePath(); 
              //得到路径,做为递归调用的开始
   CString strTitle = ff.GetFileName();
            //得到目录名

   SearchFile(strPath);//递归调用
  }
  else if(!ff.IsDirectory() && !ff.IsDots())//到达最低层的文件
  {
   CString strPath;
   CString strTitle;
   strPath = ff.GetFilePath();
   strTitle = ff.GetFileName();
   //这里用标准C的rename()或者是API的MoveFile来将文件改名,不知道楼主要用什么改名.
   //所以就不写了......

  }
 }
 ff.Close();//关闭
}
调用方法:Rename_File(欲改名的路径)


附rename()的调用实例:
void main( void )
{
   int  result;
   char old[] = "RENAMER.OBJ", new[] = "RENAMER.JBO";

   /* Attempt to rename file: */
   result = rename( old, new );
   if( result != 0 )
      printf( "Could not rename '%s'\n", old );
   else
      printf( "File '%s' renamed to '%s'\n", old, new );
}

#3


上面的代码贴出来时,作了一些修改,还有一两处没改到,不好意思,重发:

void Rename_File(CString strDir)
{
 CFileFind ff;
 CString szDir = strDir;
 
 if(szDir.Right(1) != "\\")
  szDir += "\\";
 
 szDir += "*.*";
 
 BOOL res = ff.FindFile(szDir);
 while(res)
 {
  res = ff.FindNextFile();
  
  
  if(ff.IsDirectory() && !ff.IsDots())//目录是文件夹
  {
   CString strPath = ff.GetFilePath(); 
   CString strTitle = ff.GetFileName();
   Rename_File(strPath);
  }
  else if(!ff.IsDirectory() && !ff.IsDots())
  {
   CString strPath;
   CString strTitle;
   strPath = ff.GetFilePath();
   strTitle = ff.GetFileName();
   //这里用标准C的rename()或者是API的MoveFile来将文件改名,不知道楼主要用什么改名.
   //所以就不写了......

  }
 }
 ff.Close();//关闭
}

#4


TO:zhouhuahai(道号"虚无") 
标准C语言或用C++Builder的都可以,VC我不会用啊。

#5


谢谢zhouhuahai的热心帮助。不过,你的代码应该也不行,与我用C++Builder代码做的类似,主要是文件改名后,还会再改!比如,abc.doc会改成abc.doc.eee.eee.eee.eee等。我的函数如下。

void __fastcall TForm1::RenameFiles(int flag)
//flag=1时,加上.eee后缀
//flag=2时,去除.eee后缀
{
  TSearchRec sr;
  AnsiString DestName;
  if(FindFirst("*.*",faAnyFile,sr)==0)
  {
    do
    {
      if((sr.Attr&faDirectory)&&(sr.Name!=".")&&(sr.Name!=".."))
     //如是子目录(不包括.和..子目录)
      {
        chdir(sr.Name.c_str());
        RenameFiles(flag); //调用递归函数
        chdir("..");
      }
      else if((sr.Name!=".")&&(sr.Name!=".."))
      {
        if(flag==1)
        {
//        ShowMessage(sr.Name);
          RenameFile(sr.Name,sr.Name+".eee");  //文件改名,加上.eee后缀
        }
        else
        {
          if(AnsiString(sr.Name).SubString(AnsiString(sr.Name).Length()-3,4).UpperCase()==".eee")
          {
            DestName=AnsiString(sr.Name).Delete(AnsiString(sr.Name).Length()-3,4);
          }
          RenameFile(sr.Name,DestName);   //文件改名,去除.eee后缀
        }
      }
    }while(FindNext(sr)==0);
  }
  FindClose(sr);
}

#6


这样不稳妥
如果你要把一个文件夹下的文件名字都改变成001,002,003,、、、、
这样的,而原来的实际的名字是 020,001,021。。。
那么按照搜索的机制,第一个020改成001就不成功,因为001已经在目录当中存在了

安全的做法是
先把已经有的文件的名字全部提取成一个列表当中,然后判别它是否可以这样做
对于那些已经存在名字是无需处理的

#7


“如果你要把一个文件夹下的文件名字都改变成001,002,003,、、、、
这样的,而原来的实际的名字是 020,001,021。。。
那么按照搜索的机制,第一个020改成001就不成功,因为001已经在目录当中存在了”
我不存在这个问题,因为我的改名只是将它加上.eee的后缀名。
不过你的“先把已经有的文件的名字全部提取成一个列表当中”提醒了我,可以先全部提取到一个列表中,等搜索完后,再改名,可能就可以了。谢谢!

#8


改名是否成功有多种因素的
1 同名文件或者文件夹存在不能
2 隐藏或者只读或者系统属性下不能改名
3 文件被打开状态不能改名
......

简单的写一个Find Rename结构不是具有普遍性的功能
需要有一个安全的机制来处理它

#9


如果要达到楼主的功能, 可以用一个string数组来保存找到的文件名.在查找结束后再统一进行改名.

#10


专业顶贴 兼职接分 ^_^

#11


以下是用C写的程序,把某目录下所有文件的头一个字母都改成大写A。

#include <stdio.h>
#include <dir.h>
#include <dos.h>
#include <stdlib.h>
#include <string.h>

void tracedir(char *);

int main(void)
{
char *cpRoute = "c:\\tcwin\\output\\test\\";
tracedir(cpRoute);
return 0;
}


void tracedir(char *cpDir)
{
char *cpOldName, *cpNewName, *cpDirectory, *cpTemp;
struct ffblk FFileStru;
int iReturnValue, iLength;
iLength = strlen(cpDir);
cpDirectory = (char*)malloc(iLength+4);
strcpy(cpDirectory, cpDir);
strcat(cpDirectory, "*.*");
iReturnValue = findfirst(cpDirectory, &FFileStru, 0);
while(!iReturnValue)
{
cpOldName = (char*)malloc(iLength+strlen(FFileStru.ff_name)+1);
strcpy(cpOldName, cpDir);
strcat(cpOldName, FFileStru.ff_name);
cpNewName = (char*)malloc(iLength+strlen(FFileStru.ff_name)+1);
*FFileStru.ff_name = 'A';
strcpy(cpNewName, cpDir);
strcat(cpNewName, FFileStru.ff_name);
rename(cpOldName, cpNewName);
free(cpOldName);
free(cpNewName);
iReturnValue = findnext(&FFileStru);
}
iReturnValue = findfirst(cpDirectory, &FFileStru, FA_DIREC);
while(!iReturnValue)
{
if(strcmp(FFileStru.ff_name, ".") && strcmp(FFileStru.ff_name, ".."))
{
cpTemp = (char*)malloc(iLength+strlen(FFileStru.ff_name)+3);
strcpy(cpTemp, cpDir);
strcat(cpTemp, FFileStru.ff_name);
strcat(cpTemp, "\\");
tracedir(cpTemp);
free(cpTemp);
}
iReturnValue = findnext(&FFileStru);
}
free(cpDirectory);
return;
}

#12


漏写了会遍历所有子目录。

#13


先判断,如果文件的扩展名是.eee就不要改了。