当前位置: 首页 > news >正文

C#/.NET 移动或重命名一个文件夹(如果存在,则合并而不是出现异常报错)

.NET 提供了一个简单的 API 来移动一个文件夹 Directory.Move(string sourceDirName, string destDirName)。不过如果你稍微尝试一下这个 API 就会发现其实相当不实用。


在使用 Directory.Move(string sourceDirName, string destDirName) 这个 API 来移动文件夹的时候,比如我们需要将 A 文件夹移动成 B 文件夹(也可以理解成重命名成 B)。

一旦 B 文件夹是存在的,那么这个时候会抛出异常。

抛出了异常

然而实际上我们可能希望这两个文件夹能够合并。

.NET 的 API 没有原生提供合并两个文件夹的方法,所以我们需要自己实现。

方法是递归遍历里面的所有文件,然后将源文件夹中的文件依次移动到目标文件夹中。为了应对复杂的文件夹层次结构,我写的方法中也包含了递归。

private static void MoveDirectory(string sourceDirectory, string targetDirectory)
{
    MoveDirectory(crashFolder, crashFolder + ".bak", 0);

    void MoveDirectory(string source, string target, int depth)
    {
        if (!Directory.Exists(source))
        {
            return;
        }

        if (!Directory.Exists(target))
        {
            Directory.CreateDirectory(target);
        }

        var sourceFolder = new DirectoryInfo(source);
        foreach (var fileInfo in sourceFolder.EnumerateFiles("*", SearchOption.TopDirectoryOnly))
        {
            var targetFile = Path.Combine(target, fileInfo.Name);

            if (File.Exists(targetFile))
            {
                File.Delete(targetFile);
            }

            File.Move(fileInfo.FullName, targetFile);
        }

        foreach (var directoryInfo in sourceFolder.EnumerateDirectories("*", SearchOption.TopDirectoryOnly))
        {
            var back = string.Join('\\', Enumerable.Repeat("..", depth));
            MoveFolder(directoryInfo.FullName,
                Path.GetFullPath(Path.Combine(target, back, directoryInfo.Name)), depth + 1);
        }

        Directory.Delete(source);
    }
}

depth 是一个整型,表示递归深度。我在计算文件需要移动到的新文件夹的路径的时候,需要使用到这个递归深度,以便回溯到最开始需要移动的那个文件夹上。


我的博客会首发于 https://blog.walterlv.com/,而 CSDN 会从其中精选发布,但是一旦发布了就很少更新。

如果在博客看到有任何不懂的内容,欢迎交流。我搭建了 dotnet 职业技术学院 欢迎大家加入。

知识共享许可协议

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名吕毅(包含链接:https://walterlv.blog.csdn.net/),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系。

相关文章:

  • 如何创建应用程序清单文件 App.Manifest,如何创建不带清单的应用程序
  • 应用程序清单 Manifest 中各种 UAC 权限级别的含义和效果
  • 启用 Windows 审核模式(Audit Mode),以 Administrator 账户来设置电脑的开箱体验
  • Windows 中的 UAC 用户账户控制
  • Windows 下使用 runas 命令以指定的权限启动一个进程(非管理员、管理员)
  • Windows 的 UAC 设置中的通知等级实际上只有两个档而已
  • Windows 系统上使用任务管理器查看进程的各项属性(命令行、DPI、管理员权限等)
  • C#/.NET 如何获取一个异常(Exception)的关键特征,用来判断两个异常是否表示同一个异常
  • C#/.NET 如何在第一次机会异常 FirstChanceException 中获取比较完整的异常堆栈
  • C#/.NET 使用 git 命令行来操作 git 仓库
  • C#/.NET 中启动进程时所使用的 UseShellExecute 设置为 true 和 false 分别代表什么意思?
  • WPF 的命令的自动刷新时机——当你 CanExecute 会返回 true 但命令依旧不可用时可能是这些原因
  • 将 C++/WinRT 中的线程切换体验带到 C# 中来(WPF 版本)
  • 如何在 MSBuild 的项目文件 csproj 中获取绝对路径
  • C# 跨设备前后端开发探索
  • 分享的文章《人生如棋》
  • canvas 绘制双线技巧
  • CentOS 7 修改主机名
  • CSS实用技巧干货
  • Docker 笔记(1):介绍、镜像、容器及其基本操作
  • Invalidate和postInvalidate的区别
  • JavaScript 基本功--面试宝典
  • laravel5.5 视图共享数据
  • Linux编程学习笔记 | Linux IO学习[1] - 文件IO
  • Puppeteer:浏览器控制器
  • Python中eval与exec的使用及区别
  • 码农张的Bug人生 - 见面之礼
  • 推荐一个React的管理后台框架
  • 学习笔记DL002:AI、机器学习、表示学习、深度学习,第一次大衰退
  • 一道面试题引发的“血案”
  • 一起参Ember.js讨论、问答社区。
  • 以太坊客户端Geth命令参数详解
  • 京东物流联手山西图灵打造智能供应链,让阅读更有趣 ...
  • ​linux启动进程的方式
  • #Z0458. 树的中心2
  • (10)ATF MMU转换表
  • (145)光线追踪距离场柔和阴影
  • (2)MFC+openGL单文档框架glFrame
  • (Mac上)使用Python进行matplotlib 画图时,中文显示不出来
  • (Oracle)SQL优化技巧(一):分页查询
  • (二)丶RabbitMQ的六大核心
  • (附源码)spring boot校园健康监测管理系统 毕业设计 151047
  • (介绍与使用)物联网NodeMCUESP8266(ESP-12F)连接新版onenet mqtt协议实现上传数据(温湿度)和下发指令(控制LED灯)
  • .mysql secret在哪_MYSQL基本操作(上)
  • .NET CF命令行调试器MDbg入门(四) Attaching to Processes
  • .NET Core WebAPI中使用Log4net 日志级别分类并记录到数据库
  • .NET Framework 的 bug?try-catch-when 中如果 when 语句抛出异常,程序将彻底崩溃
  • .net 提取注释生成API文档 帮助文档
  • .NET成年了,然后呢?
  • .NET轻量级ORM组件Dapper葵花宝典
  • @RequestParam详解
  • [ACTF2020 新生赛]Include
  • [C puzzle book] types
  • [Codeforces] number theory (R1600) Part.11
  • [daily][archlinux][game] 几个linux下还不错的游戏