在 C# 中,如何一次组合文件路径的两个以上部分?

Posted

技术标签:

【中文标题】在 C# 中,如何一次组合文件路径的两个以上部分?【英文标题】:In C#, how do I combine more than two parts of a file path at once? 【发布时间】:2011-01-01 01:18:37 【问题描述】:

要组合文件路径的两个部分,您可以这样做

System.IO.Path.Combine (path1, path2);

但是,你不能这样做

System.IO.Path.Combine (path1, path2, path3);

有没有简单的方法来做到这一点?

【问题讨论】:

【参考方案1】:

这是一个你可以使用的实用方法:

public static string CombinePaths(string path1, params string[] paths)

    if (path1 == null)
    
        throw new ArgumentNullException("path1");
    
    if (paths == null)
    
        throw new ArgumentNullException("paths");
    
    return paths.Aggregate(path1, (acc, p) => Path.Combine(acc, p));

替代代码高尔夫版本(更短,但不太清楚,语义与Path.Combine 有点不同):

public static string CombinePaths(params string[] paths)

    if (paths == null)
    
        throw new ArgumentNullException("paths");
    
    return paths.Aggregate(Path.Combine);

那么你可以这样称呼它:

string path = CombinePaths(path1, path2, path3);

【讨论】:

这可能是一个愚蠢的问题,但聚合从何而来?我正在使用针对 Mono / .Net 3.5 的 Mono,编译器找不到它。 啊——AggregateSystem.Linq命名空间中的扩展方法,在System.Core.dll中。 为什么有额外的 'path1' 参数?另外,最后一行可以缩短为return paths.Aggregate(/*path1, */Path.Combine); @Kha:这是真的,我这样写是为了保留原始Path.Combine 的语义,并试图清楚地表明该方法至少需要一个路径才能正常工作。如果path1path2nullPath.Combine 将抛出ArgumentNullException。但你说得对,这不是完全必要的。 Kha:我更喜欢那个简单的版本。我编辑了我的问题以包含修改后的实用程序方法。【参考方案2】:

正如其他人所说,在 .NET 3.5 和更早版本中,还没有一种方法可以巧妙地做到这一点 - 您要么必须编写自己的 Combine 方法,要么多次调用 Path.Combine

但庆幸 - 在 .NET 4.0 中,有 this overload:

public static string Combine(
    params string[] paths
)

还有采用 3 或 4 个字符串的重载,大概是为了在常见情况下不需要创建不必要的数组。

希望 Mono 能尽快移植这些重载 - 我相信它们很容易实现并且非常感谢。

【讨论】:

不应该声明单个数组比声明 4 个不同的变量更有效吗? 4 或 3 字符串过载的原因可能是什么? @Hasan:不,创建一个数组需要一个单独的对象,该对象必须在以后进行垃圾回收等。传递两个单独的变量比创建一个包含两个引用的新数组更有效。 无需等待,从 10/21/09 开始实施 :) anonsvn.mono-project.com/… msdn.microsoft.com/en-us/library/dd784047(VS.90).aspx 声明 Path.Combine 在 .Net 3.5 中将采用 3 个字符串,这显然是错误的,因为它在使用时会出现编译器错误。在这种情况下,msdn 库是错误的。我把它放在这里以防其他人在收到此编译器错误后登陆此页面。 既然 .NET 4.0 已经发布,我已将接受的答案更改为这个答案。【参考方案3】:

不简单,但很聪明:)

string str1 = "aaa", str2 = "bbb", str3 = "ccc";
string comb = new string[]  str1, str2, str3 
    .Aggregate((x, y) => System.IO.Path.Combine(x, y));

或者:

string CombinePaths(params string[] paths)

    return paths.Aggregate((x,y) => System.IO.Path.Combine(x, y));

编辑 Order23 的答案实际上是最新的与当前.NET https://***.com/a/41148772/235648

【讨论】:

如果您不多次这样做,这很方便。不过,您可以简化很多:new [] "aaa", "bbb", "ccc" .Aggregate (Path.Combine);(假设您是 using System.IO;)。【参考方案4】:

不,您必须多次致电Path.Combine()

不过,你可以编写一个辅助方法来为你做这件事:

public static string CombinePaths(params string[] paths) 
    if (paths == null) 
        return null;
    
    string currentPath = paths[0];
    for (int i = 1; i < paths.Length; i++) 
        currentPath = Path.Combine(currentPath, paths[i]);
    
    return currentPath;

【讨论】:

看一下逻辑,您可以轻松摆脱第二个 if 语句。 @ChaosPandion:如果您要避免使用 Linq,那么您还应该优化 Schlemiel-the-painter 算法,而是使用带有 StringBuilder 的 Path.PathSeparator 和其他静态字段。我认为性能在这里不是问题。 “不必要的 LINQ”?也许你忘了指定 [.net-2.0] 标签? @ChaosPandion - “不必要的 Linq”?也许——如果性能很关键。或者如果只有 .Net 2。但实际上 Linq 方法是简单、简洁和有意的。如果它能让人们从功能角度思考,那也不是坏事。 我和其他人一样喜欢 LINQ,但是为了这么简单的事情来吧?你们需要放轻松。【参考方案5】:

使用 .NET 4 Path.Combine(string []) 中引入的方法重载

Path.Combine(new []  "abc", "def", "ghi", "jkl", "mno" );

【讨论】:

以上是关于在 C# 中,如何一次组合文件路径的两个以上部分?的主要内容,如果未能解决你的问题,请参考以下文章

c#中如何访问虚拟目录路径?

如何在c#中动态组合两个或多个DataTables

如何使用c#从两个以上的MS Access数据库表中检索数据

如何在 c# wpf 中一次加载/保存多个文件? [关闭]

如何从 C# 中的文件路径中去除引号和命令行参数?

在C#中如何将多个rtf文件内容组合在一起用一个rtf文件保存?