You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在MailKit中创建/获取含多级子文件夹的目录(带路径分隔符)

使用MailKit创建多级IMAP文件夹的问题

我用MailKit创建文件夹时,一级文件夹的创建很简单——在父文件夹上调用CreateFolderAsync(异步方式)即可,示例代码如下:

public async Task<IMailFolder> GetOrCreateFolder(string folderName)
{
    var rootFolder = await authenticatedClient.GetFolderAsync(imapClient.PersonalNamespaces[0].Path);
    var existingFolders = await rootFolder.GetSubfoldersAsync();
    var matchingFolder = existingFolders.FirstOrDefault(folder => folder.FullName == folderName);

    if (matchingFolder == null)
    {
        matchingFolder = await rootFolder.CreateAsync(folderName, true);
    }

    return matchingFolder;
}

但如果传入带层级的路径,比如GetOrCreateFolder("folder/subfolder")或GetOrCreateFolder("folder.subfolder")(后续发现很多IMAP服务器用.作为目录分隔符,可通过IMailFolder.DirectorySeparator获取),就会抛出异常:The name is not a legal folder name,具体异常信息如下:

System.ArgumentException
  HResult=0x80070057
  Nachricht = The name is not a legal folder name. Arg_ParamName_Name
  Quelle = MailKit
  Stapelüberwachung:
   bei MailKit.Net.Imap.ImapFolder.QueueCreateCommand(String name, Boolean isMessageFolder, CancellationToken cancellationToken, String& encodedName)
   bei MailKit.Net.Imap.ImapFolder.CreateAsync(String name, Boolean isMessageFolder, CancellationToken cancellationToken)
   // ...

  Diese Ausnahme wurde ursprünglich von dieser Aufrufliste ausgelöst:
    MailKit.Net.Imap.ImapFolder.QueueCreateCommand(string, bool, System.Threading.CancellationToken, out string)
    MailKit.Net.Imap.ImapFolder.CreateAsync(string, bool, System.Threading.CancellationToken)

硬编码先创建一级再创建二级的方式太不灵活,Linux的mkdir都支持一次性创建多级文件夹,请问怎么灵活解决这个问题?


解决方案:递归创建多级文件夹

要实现类似mkdir -p的效果,需要拆分路径为层级目录,从根目录开始逐级检查并创建不存在的文件夹,具体实现如下:

public async Task<IMailFolder> GetOrCreateNestedFolder(string folderPath)
{
    var rootFolder = await authenticatedClient.GetFolderAsync(imapClient.PersonalNamespaces[0].Path);
    char separator = rootFolder.DirectorySeparator;
    
    // 拆分路径,过滤空字符串(避免路径开头/结尾的分隔符导致无效项)
    var folderNames = folderPath.Split(new[] { separator, '/' }, StringSplitOptions.RemoveEmptyEntries);
    
    var currentFolder = rootFolder;
    foreach (var folderName in folderNames)
    {
        var subfolders = await currentFolder.GetSubfoldersAsync();
        var existingFolder = subfolders.FirstOrDefault(f => f.Name.Equals(folderName, StringComparison.OrdinalIgnoreCase));
        
        if (existingFolder == null)
        {
            existingFolder = await currentFolder.CreateAsync(folderName, true);
        }
        
        currentFolder = existingFolder;
    }
    
    return currentFolder;
}

代码说明:

  • 兼容两种分隔符:同时处理服务器原生分隔符(如.)和通用的/,适配不同格式的路径输入
  • 大小写不敏感匹配:用StringComparison.OrdinalIgnoreCase判断文件夹是否存在,兼容部分IMAP服务器的大小写特性
  • 逐级创建:从根目录开始遍历每一层,确保所有父文件夹都存在,最终返回目标的多级文件夹

内容的提问来源于stack exchange,提问作者rklec

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 22:28:24