C#批量重命名文件 C#如何循环修改文件夹下的文件名

1次阅读

Directory.GetFiles 获取文件后用 File.Move 批量重命名最可靠:需清除只读属性、校验目标路径、手动解析多点扩展名、逐文件异常捕获并记录。

C#批量重命名文件 C#如何循环修改文件夹下的文件名

Directory.GetFiles 获取所有文件再批量重命名

直接遍历目标文件夹下的文件是第一步,Directory.GetFilesDirectory.EnumerateFiles 更适合批量操作,因为返回的是完整路径数组,便于后续统一处理。注意要指定搜索选项(如 SearchOption.AllDirectories)来控制是否递归子目录。

常见错误是忽略文件只读属性或权限问题,导致 File.Move 抛出 UnauthorizedaccessExceptionIOException。建议先用 FileAttributes.ReadOnly 检查并清除只读位:

var files = Directory.GetFiles(@"C:MyFolder", "*.*", SearchOption.TopDirectoryOnly); foreach (var file in files) {     var attr = File.GetAttributes(file);     if ((attr & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)         File.SetAttributes(file, attr & ~FileAttributes.ReadOnly); 
var dir = Path.GetDirectoryName(file); var ext = Path.GetExtension(file); var newName = Path.Combine(dir, "prefix_" + Path.GetFileNameWithoutExtension(file) + ext); File.Move(file, newName);

}

File.Move 是重命名的唯一可靠方式

C# 中没有独立的“重命名”函数,File.Move 是实际且唯一推荐的方式——它在同卷(同一磁盘分区)下是原子重命名操作,不涉及内容复制,速度快、安全。跨卷调用 File.Move 会自动转为复制+删除,此时若中途失败可能留下残留文件。

关键注意事项:

  • File.Move 的第二个参数(新路径)必须包含完整文件名和扩展名,不能只传新文件名
  • 目标路径不能已存在,否则抛出 IOException;需提前用 File.Exists 判断并处理冲突(如跳过、覆盖或加序号)
  • 不要用 File.copy + File.delete 替代,容易出竞态或残留

按规则生成新文件名时慎用 Path.GetFileNameWithoutExtension

这个方法看似方便,但对含多个点的文件名(如 archive.tar.gz)会截掉第一个点之后全部内容,变成 archive,丢失真实扩展名。如果想保留完整扩展链,应手动解析或改用正则匹配最后的点位置。

更稳妥的做法:

string fileName = Path.GetFileName(file); int lastDot = fileName.LastIndexOf('.'); string namePart = lastDot > 0 ? fileName.Substring(0, lastDot) : fileName; string extPart = lastDot > 0 ? fileName.Substring(lastDot) : ""; string newName = Path.Combine(dir, $"v2_{namePart}{extPart}");

另外,windows 文件系统对大小写不敏感,但 File.Move 传入大小写不同的名字(如 FILE.TXTfile.txt)仍会成功,这在某些场景下可能造成混淆,需明确业务是否需要保持大小写一致性。

批量操作前务必加异常捕获和日志输出

文件系统操作不可逆,尤其批量重命名一旦出错(比如路径拼错、编码异常、中文乱码),可能让整个文件夹陷入混乱。不要依赖 try-catch 包裹整个循环——那样会掩盖具体哪一步失败。

推荐逐文件 try-catch,并记录失败项:

foreach (var file in files) {     try     {         // ... 构造 newName         File.Move(file, newName);         console.WriteLine($"OK: {Path.GetFileName(file)} → {Path.GetFileName(newName)}");     }     catch (Exception ex)     {         Console.WriteLine($"FaiL: {Path.GetFileName(file)} — {ex.Message}");         // 可选:写入日志文件或收集 failedList     } }

特别注意:如果文件名含 Unicode 字符(如中文、emoji),确保控制台或日志编码支持 UTF-8,否则 Console.WriteLine 可能显示乱码,但不影响实际重命名结果。

真正麻烦的不是语法,而是路径拼接时的斜杠方向、相对/绝对路径混用、以及没检查目标文件是否存在就强行覆盖——这些细节一错,整批文件就可能被误删或覆盖。

text=ZqhQzanResources