c#中是否有任何函数来回显文件路径?
输入:“c:\ users \ Windows \ Downloaded Program Files \ Folder \ Inside \ example \ file.txt”
输出:“c:\ users \ ... \ example \ file.txt”
答案 0 :(得分:6)
对我而言,这看起来不那么人性化。无论如何,我认为没有这样的功能。将它分开在\字符上,只保留前两个插槽和最后两个插槽即可。
这样的东西,虽然代码不是很优雅
string[] splits = path.Split('\\');
Console.WriteLine( splits[0] + "\\" + splits[1] + "\\...\\" + splits[splits.Length - 2] + "\\" + splits[splits.Length - 1]);
答案 1 :(得分:5)
Nasreddine的答案几乎是正确的。 只需指定StringBuilder大小,在您的情况下:
[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();
}
答案 2 :(得分:3)
如果要根据路径字符串的长度插入省略号,请使用以下代码:
TextRenderer.MeasureText(path, Font,
new System.Drawing.Size(Width, 0),
TextFormatFlags.PathEllipsis | TextFormatFlags.ModifyString);
它会就地修改path
。
编辑:请注意此方法。它打破了规则,说.NET中的字符串是不可变的。实际上,MeasureText
方法的第一个参数不是ref
参数,这意味着不能返回新的字符串。而是改变现有的字符串。处理使用
string temp = String.Copy(path);
答案 3 :(得分:3)
Jeff Atwood posted在他的博客上解决了这个问题,现在是:
[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();
PathCompactPathEx(sb, path, length, 0);
return sb.ToString();
}
它使用非托管函数PathCompactPathEx
来实现您想要的功能。
答案 4 :(得分:2)
您可以使用以下内容:
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;
}
或者只使用Olivers解决方案,这更容易; - )。
答案 5 :(得分:1)
我刚刚面对这个问题,因为很长的路径正在成为一个完整的眼睛疼痛。这就是我快速拼凑在一起的东西(记住邋iness),但它完成了工作。
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;
}
修改
以下是Merlin2001更正的更新。
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);
}
return output;
}
答案 6 :(得分:1)
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;
}
答案 7 :(得分:1)
如果要编写自己的解决方案,请使用诸如 FileInfo , Directory 等之类的内建类,这样可以减少出错的可能性。
以下代码生成“ VS风格”的缩短路径,例如:“ C:\ ... \ Folder \ File.ext”。
public static class PathFormatter
{
public static string ShrinkPath(string absolutePath, int limit, string spacer = "…")
{
if (string.IsNullOrWhiteSpace(absolutePath))
{
return string.Empty;
}
if (absolutePath.Length <= limit)
{
return absolutePath;
}
var parts = new List<string>();
var fi = new FileInfo(absolutePath);
string drive = Path.GetPathRoot(fi.FullName);
parts.Add(drive.TrimEnd('\\'));
parts.Add(spacer);
parts.Add(fi.Name);
var ret = string.Join("\\", parts);
var dir = fi.Directory;
while (ret.Length < limit && dir != null)
{
if (ret.Length + dir.Name.Length > limit)
{
break;
}
parts.Insert(2, dir.Name);
dir = dir.Parent;
ret = string.Join("\\", parts);
}
return ret;
}
}
答案 8 :(得分:0)
这里几乎所有的答案都通过计算字符来缩短路径字符串。 但是这种方法忽略了每个字符的宽度。
这些是 30 个“W”字符:
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
这些是 30 个“i”字符:
iiiiiiiiiiiiiiiiiiiiiiiiiiiiii
如您所见,计算字符并不是很有用。
而且无需编写您自己的代码,因为 Windows API 自 Windows 95 起就具有此功能。
此功能的名称是“路径省略号”。
Windows API DrawTextW()
有一个标志 DT_PATH_ELLIPSIS
正是这样做的。
在 .NET 框架中,这在 TextRenderer
类中可用(无需使用 PInvoke)。
有两种使用方法:
1.) 将路径直接绘制到标签中:
public class PathLabel : Label
{
protected override void OnPaint(PaintEventArgs e)
{
if (AutoSize)
throw new Exception("You must set "+Name+".AutoSize = false in VS "
+ "Designer and assign a fix width to the PathLabel.");
Color c_Fore = Enabled ? ForeColor : SystemColors.GrayText;
TextRenderer.DrawText(e.Graphics, Text, Font, ClientRectangle, c_Fore,
BackColor, TextFormatFlags.PathEllipsis);
}
}
此标签要求您在 Visual Studio 设计器中关闭 AutoEllipsis
并为标签指定一个固定宽度(您的路径应占据的最大宽度)。
您甚至可以在 Visual Studio 设计器中看到被截断的路径。
我输入了一条不适合标签的长路径:
C:\WINDOWS\Installer{40BF1E83-20EB-11D8-97C5-0009C5020658}\ARPPRODUCTICON.exe
即使在 Visual Studio 设计器中,它也是这样显示的:
2.) 缩短路径而不在屏幕上绘制:
public static String ShortenPath(String s_Path, Font i_Font, int s32_Width)
{
TextRenderer.MeasureText(s_Path, i_Font, new Size(s32_Width, 100),
TextFormatFlags.PathEllipsis | TextFormatFlags.ModifyString);
// Windows inserts a '\0' character into the string instead of shortening the string
int s32_Nul = s_Path.IndexOf((Char)0);
if (s32_Nul > 0)
s_Path = s_Path.Substring(0, s32_Nul);
return s_Path;
}
标志 TextFormatFlags.ModifyString
在字符串中插入一个 '\0' 字符。在 C# 中修改字符串是非常不寻常的。
通常字符串是不可变的。
这是因为底层 API DrawTextW()
以这种方式工作。
但由于字符串只会缩短而永远不会变长,因此不存在缓冲区溢出的风险。
以下代码
String s_Text = @"C:\WINDOWS\Installer{40BF1E83-20EB-11D8-97C5-0009C5020658}\ARPPRODUCTICON.exe";
s_Text = ShortenPath(s_Text, new Font("Arial", 12), 500);
将导致“C:\WINDOWS\Installer{40BF1E83-20EB-1...\ARPPRODUCTICON.exe”