Directory.GetFiles 获取文件后用 File.Move 批量重命名最可靠:需清除只读属性、校验目标路径、手动解析多点扩展名、逐文件异常捕获并记录。
用 Directory.GetFiles 获取所有文件再批量重命名
直接遍历目标文件夹下的文件是第一步,Directory.GetFiles 比 Directory.EnumerateFiles 更适合批量操作,因为返回的是完整路径数组,便于后续统一处理。注意要指定搜索选项(如 SearchOption.AllDirectories)来控制是否递归子目录。
常见错误是忽略文件只读属性或权限问题,导致 File.Move 抛出 UnauthorizedAccessException 或 IOException。建议先用 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,丢失真实扩展名。如果想保留完整扩展链,应手动解析或改用正则匹配最后的点位置。
更稳妥的做法: