Is there any function in c# to shink a file path ?
Input: \"c:\\users\\Windows\\Downloaded Program Files\\Folder\\Inside\\example\\file.txt\"
<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 ;-).
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;
}
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));
}
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]);
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);
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();
}
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;
}