2013-02-12 118 views
1

在.NET中(VB或C#)有谁知道从文件路径字符串中删除'head'目录的简单方法,这意味着如果我的路径看起来像这样:Directory1/Directory2/Directory3我想要Directory2/Directory3回来。我知道有一些方法可以做到这一点,比如将它分解成一个数组,然后从第二个元素开始将它们连接起来,我只是觉得这样,这是一种非常低效的方法,并且想知道是否存在一个更好的方法来做到这一点。从文件路径中删除'head'目录

+0

这是什么效率有什么关系呢?你真的会这么频繁地打电话,以至于你担心几微秒? – 2013-02-12 18:56:29

+1

“非常低效”的方式是通过拨号连接将其写入服务器,然后将其读回。一个两元素临时数组甚至不会注册。 – millimoose 2013-02-12 19:00:41

+0

**正确性**几乎总是高效......在这种情况下请查看System.IO.Path以帮助确保正确性。 – 2013-02-12 19:01:01

回答

4

这取决于你在找什么。如果你知道事情的形式为dir1/dir2/dir3/dir4...,那么你可以找第一/和拍照后,一切:

string dir = "dir1/dir2/dir3"; 
var pos = dir.IndexOf('/'); 
if (pos != -1) 
{ 
    result = dir.Substring(pos+1); 
} 

如果你也能接受的形式c:\dir\dir\file.ext\\server\dir\dir\file.ext的全路径名,那么你我们可能会想确保你先将任何相对路径变成完整路径。然后使用System.IO.Path类中的方法在使用类似上面的IndexOf技巧之前提取驱动器或服务器名称。

0

看看System.IO.Path这个课。对于这种事情有很多有用的方法。

例如,你可以使用它的方法GetPathRoot()像这样以与string.replace()的调用的一部分:

public string RemoveHead(string path) 
{ 
    return path.Replace(Path.GetPathRoot(path), ""); 
} 

我没有Visual Studio中得心应手,让可能需要一些调整帐户分隔符或驱动器号,但它应该给你的想法。

+1

但'GetPathRoot'将为'directory1 \ directory2 \ directory3'返回一个空字符串。 – 2013-02-12 19:03:46

0

如果你想正确性和效率,

string [email protected]"dir1/dir2/dir3"; 
path=path.Substring(path.IndexOf(System.IO.Path.DirectorySeparatorChar)+1); 

只有1个新的字符串被创建。

0
 /// <summary> 
    /// Removes head. 
    /// </summary> 
    /// <param name="path">The path to drop head.</param> 
    /// <param name="retainSeparator">If to retain separator before next folder when deleting head.</param> 
    /// <returns>New path.</returns> 
    public static string GetPathWithoutHead (string path, bool retainSeparator = false) 
    { 
     if (path == null) 
     { 
      return path; 
     } 
     if (string.IsNullOrWhiteSpace (path)) 
     { 
      throw new ArgumentException(path, "The path is not of a legal form."); 
     } 

     var root = System.IO.Path.GetPathRoot (path); 
     if (!string.IsNullOrEmpty(root) && !StartsWithAny(root,System.IO.Path.DirectorySeparatorChar,System.IO.Path.AltDirectorySeparatorChar)) 
     {    
      return path.Remove(0,root.Length); 
     } 

     var sep = path.IndexOf(System.IO.Path.DirectorySeparatorChar); 
     var altSep = path.IndexOf(System.IO.Path.AltDirectorySeparatorChar); 
     var pos = MaxPositiveOrMinusOne (sep, altSep); 
     if (pos == -1) 
     { 
      return string.Empty; 
     } 

     if (pos == 0) 
     { 
      return GetPathWithoutHead(path.Substring(pos+1), retainSeparator); 
     } 

     var eatSeparator = !retainSeparator ? 1 : 0; 
     return path.Substring(pos+eatSeparator); 
    } 

    /// <summary> 
    /// Startses the with. 
    /// </summary> 
    /// <returns><c>true</c>, if with was startsed, <c>false</c> otherwise.</returns> 
    /// <param name="val">Value.</param> 
    /// <param name="maxLength">Max length.</param> 
    /// <param name="chars">Chars.</param> 
    private static bool StartsWithAny(string value, params char[] chars) 
    { 
     foreach (var c in chars) 
     { 
      if (value[0] == c) 
      { 
       return true; 
      } 
     } 
     return false; 
    } 

    /// <summary> 
    /// Maxs the positive or minus one. 
    /// </summary> 
    /// <returns>The positive or minus one.</returns> 
    /// <param name="val1">Val1.</param> 
    /// <param name="val2">Val2.</param> 
    private static int MaxPositiveOrMinusOne(int val1, int val2) 
    { 
     if (val1 < 0 && val2 < 0) 
     { 
      return -1; 
     } 
     return Math.Max(val1,val2: val2); 
    } 

Several unit tests are here