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

来源:这里教程网 时间:2026-02-21 17:41:22 作者:

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);
<pre class='brush:php;toolbar:false;'>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.TXT
file.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
可能显示乱码,但不影响实际重命名结果。

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

相关推荐