12

I would like to truncate a long path to specific length. However, I want to have the ellipsis in the middle.

for example: \\my\long\path\is\really\long\and\it\needs\to\be\truncated should become (truncated to 35 chars): \\my\long\path\is...to\be\truncated

Is there a standard function or extension method available?

Vivek
  • 16,360
  • 5
  • 30
  • 37
  • This is also well answered in http://stackoverflow.com/questions/8360360/c-sharp-function-to-shrink-file-path-to-be-more-human-readble – Marc Durdin May 04 '15 at 21:19

3 Answers3

9

There is no standard function or extension method, so you will have to roll your own.

Check for length and use something like;

var truncated = ts.Substring(0, 16) + "..." + ts.Substring((ts.Length - 16), 16);
ChrisBint
  • 12,773
  • 6
  • 40
  • 62
  • 1
    @Elmue Thanks for your input on something that is nearly 10 years old... Did you read the requirements? Are you claiming that the requirements are wrong and that your answer must be correct as it's the only way you could possibly want to use a truncated string? – ChrisBint May 20 '21 at 14:06
  • @Elmue You appear to be making assumptions ago, is this a habit of yours? My solution was useful to the person that asked the question and a number of others since that point, hence the reason for the green tick and the greater than 0 number above it. – ChrisBint May 20 '21 at 18:25
6

Here is what I use. It very nicely create ellipsis in the middle of a path and it also allows you to speciy any length or delimiter.

Note this is an extension method so you can use it like so `"c:\path\file.foo".EllipsisString()

I doubt you need the while loop, in fact you probably don't, I was just too busy to test properly

    public static string EllipsisString(this string rawString, int maxLength = 30, char delimiter = '\\')
    {
        maxLength -= 3; //account for delimiter spacing

        if (rawString.Length <= maxLength)
        {
            return rawString;
        }

        string final = rawString;
        List<string> parts;

        int loops = 0;
        while (loops++ < 100)
        {
            parts = rawString.Split(delimiter).ToList();
            parts.RemoveRange(parts.Count - 1 - loops, loops);
            if (parts.Count == 1)
            {
                return parts.Last();
            }

            parts.Insert(parts.Count - 1, "...");
            final = string.Join(delimiter.ToString(), parts);
            if (final.Length < maxLength)
            {
                return final;
            }
        }

        return rawString.Split(delimiter).ToList().Last();
    }
Chris
  • 26,744
  • 48
  • 193
  • 345
3

This works

    // Specify max width of resulting file name
    const int MAX_WIDTH = 50;

    // Specify long file name
    string fileName = @"A:\LongPath\CanBe\AnyPathYou\SpecifyHere.txt";

    // Find last '\' character
    int i = fileName.LastIndexOf('\\');

    string tokenRight = fileName.Substring(i, fileName.Length - i);
    string tokenCenter = @"\...";
    string tokenLeft = fileName.Substring(0, MAX_WIDTH-(tokenRight.Length + tokenCenter.Length));

    string shortFileName = tokenLeft + tokenCenter + tokenRight;
fab
  • 2,479
  • 1
  • 16
  • 6
  • I like this approach, the only problem is if the filename is too big (if together tokenCenter is bigger than the max_width), it breaks the tokenLeft calculation, with an ArgumentException, because tries to substring with a negative value. – SirMartin Sep 15 '20 at 11:46