Function to shrink file path to be more human readable

前端 未结 8 712
北海茫月
北海茫月 2020-12-31 20:15

Is there any function in c# to shink a file path ?

Input: \"c:\\users\\Windows\\Downloaded Program Files\\Folder\\Inside\\example\\file.txt\"

<
相关标签:
8条回答
  • 2020-12-31 20:54

    You could use something like:

    public string ShrinkPath(string path, int maxLength)
    {
        List<string> parts = new List<string>(path.Split('\\'));
    
        string start = parts[0] + @"\" + parts[1];
        parts.RemoveAt(1);
        parts.RemoveAt(0);
    
        string end = parts[parts.Count-1];
        parts.RemoveAt(parts.Count-1);
    
        parts.Insert(0, "...");
        while(parts.Count > 1 && 
          start.Length + end.Length + parts.Sum(p=>p.Length) + parts.Count > maxLength)
            parts.RemoveAt(parts.Count-1);
    
        string mid = "";
        parts.ForEach(p => mid += p + @"\");
    
        return start+mid+end;
    }
    

    Or just use Olivers solution, which is much easier ;-).

    0 讨论(0)
  • 2020-12-31 20:54

    I was just faced with this issue as long paths were becoming a complete eye sore. Here is what I tossed together real quick (mind the sloppiness) but it gets the job done.

    private string ShortenPath(string path, int maxLength)
    {
        int pathLength = path.Length;
    
        string[] parts;
        parts = label1.Text.Split('\\');
    
        int startIndex = (parts.Length - 1) / 2;
        int index = startIndex;
    
        string output = "";
        output = String.Join("\\", parts, 0, parts.Length);
    
        decimal step = 0;
        int lean = 1;
    
        do
        {
            parts[index] = "...";
    
            output = String.Join("\\", parts, 0, parts.Length);
    
            step = step + 0.5M;
            lean = lean * -1;
    
            index = startIndex + ((int)step * lean);
        }
        while (output.Length >= maxLength && index != -1);
    
        return output;
    }
    

    Results

    EDIT

    Below is an update with Merlin2001's corrections.

    private string ShortenPath(string path, int maxLength)
    {
        int pathLength = path.Length;
    
        string[] parts;
        parts = path.Split('\\');
    
        int startIndex = (parts.Length - 1) / 2;
        int index = startIndex;
    
        String output = "";
        output = String.Join("\\", parts, 0, parts.Length);
    
        decimal step = 0;
        int lean = 1;
    
        while (output.Length >= maxLength && index != 0 && index != -1)
        {
            parts[index] = "...";
    
            output = String.Join("\\", parts, 0, parts.Length);
    
            step = step + 0.5M;
            lean = lean * -1;
    
            index = startIndex + ((int)step * lean);
        }
        // result can be longer than maxLength
        return output.Substring(0, Math.Min(maxLength, output.Length));  
    }
    
    0 讨论(0)
  • 2020-12-31 20:57

    That looks less human readable to me. Anyway, I don't think there is such a function. split it on the \ character and just keep the first two slots and the last two slots and you have it.

    Something like this, although that code is not very elegant

      string[] splits = path.Split('\\');
      Console.WriteLine( splits[0] + "\\" + splits[1] + "\\...\\" + splits[splits.Length - 2] + "\\" +  splits[splits.Length - 1]);
    
    0 讨论(0)
  • 2020-12-31 20:59

    If you want do insert ellipsis dependent on the length of the path string, then use this code:

    TextRenderer.MeasureText(path, Font, 
        new System.Drawing.Size(Width, 0),
        TextFormatFlags.PathEllipsis | TextFormatFlags.ModifyString);
    

    It will modify path in-place.

    EDIT: Be careful with this method. It breaks the rule, saying that strings in .NET are immutable. In fact, the first parameter of the MeasureText method is not a ref parameter, which means that no new string can be returned. Instead, the existing string is altered. It would be careful to work on a copy created with

    string temp = String.Copy(path);
    
    0 讨论(0)
  • 2020-12-31 21:02

    Nasreddine answer was nearly correct. Just specify StringBuilder size, in your case:

    [DllImport("shlwapi.dll", CharSet = CharSet.Auto)]
    static extern bool PathCompactPathEx(
                           [Out] StringBuilder pszOut, 
                           string szPath, 
                           int cchMax, 
                           int dwFlags);
    
    static string PathShortener(string path, int length)
    {
        StringBuilder sb = new StringBuilder(length + 1);
        PathCompactPathEx(sb, path, length, 0);
        return sb.ToString();
    }
    
    0 讨论(0)
  • 2020-12-31 21:06
        private string ShrinkPath(string path, int maxLength)
        {
            var parts = path.Split('\\');
            var output = String.Join("\\", parts, 0, parts.Length);
            var endIndex = (parts.Length - 1);
            var startIndex = endIndex / 2;
            var index = startIndex;
            var step = 0;
    
            while (output.Length >= maxLength && index != 0 && index != endIndex)
            {
                parts[index] = "...";
                output = String.Join("\\", parts, 0, parts.Length);
                if (step >= 0) step++;
                step = (step * -1);
                index = startIndex + step;
            }
            return output;
        }
    
    0 讨论(0)
提交回复
热议问题